javascript
cassandra可视化_容器化Spring Data Cassandra应用程序
cassandra可視化
我正在繼續學習Docker的旅程。 在這一點上,我仍然保持簡單。 這次,我將解決將Spring和Cassandra應用程序轉換為使用容器而不是在主機上本地運行的問題。 更確切地說,使用Spring Data Cassandra整理應用程序。
我希望我前幾天看過進行此更改。 我在Cassandra上寫了很多文章,每次我必須cd到正確的目錄或有啟動它的快捷方式時。 我想這沒什么大不了的,但是還涉及其他一些事情。 例如,刪除和重新創建鍵空間,以便我可以從頭開始測試我的應用程序。 現在,我只刪除容器并重新啟動它。 無論如何對我來說,這是有幫助的!
這篇文章與我以前的文章《 使用Docker將現有應用程序推送到容器》稍有不同。 取而代之的是,我將更加側重于應用程序端,并刪除僅使用Docker的中間步驟,而是直接跳至Docker Compose。
集裝箱集裝箱
我認為最好從項目的容器端開始,因為應用程序取決于Cassandra容器的配置。
我們走吧!
FROM openjdk:10-jre-slim LABEL maintainer="Dan Newton" ARG JAR_FILE ADD target/${JAR_FILE} app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]這里沒有太多的事情。 這個Dockerfile構建了Spring應用程序映像,稍后將其放入容器中。
接下來是docker-compose文件。 這將同時構建Spring應用程序和Cassandra容器:
version: '3' services:app:build:context: .args:JAR_FILE: /spring-data-cassandra-docker-1.0.0.jarrestart: alwayscassandra: image: "cassandra"同樣,這里沒有太多。 app容器使用Dockerfile定義的Dockerfile構建Spring應用程序。 相反, cassandra容器依賴于現有的映像,適當地命名為cassandra 。
突出的一件事是restart屬性設置為always 。 這是我懶惰的嘗試,目的是超越Cassandra啟動所需的時間,并且所有容器都以docker-compose開頭的事實是同時啟動的。 這導致應用程序在未準備就緒的情況下嘗試連接到Cassandra的情況。 不幸的是,這導致應用程序崩潰。 我希望它對內置的初始連接將有一些重試功能……但事實并非如此。
當我們遍歷代碼時,我們將看到如何以編程方式處理初始Cassandra連接,而不是依賴于應用程序死掉并多次重啟。 您仍然會看到我處理連接的版本……我不是真正的解決方案擁護者,但是我嘗試的所有其他操作都使我更加痛苦。
一點代碼
我說這篇文章將把重點更多地放在應用程序代碼上,但是我們不會深入研究我在此應用程序中放置的所有內容以及如何使用Cassandra。 有關此類信息,您可以查看我的較舊文章,這些文章將在最后鏈接。 但是,我們要做的是檢查配置代碼,該代碼創建連接到Cassandra的bean。
首先,讓我們看一下設置Cassandra集群的ClusterConfig :
@Configuration public class ClusterConfig extends AbstractClusterConfiguration {private final String keyspace;private final String hosts;ClusterConfig(@Value("${spring.data.cassandra.keyspace-name}") String keyspace,@Value("${spring.data.cassandra.contact-points}") String hosts) {this.keyspace = keyspace;this.hosts = hosts;}@Bean@Overridepublic CassandraClusterFactoryBean cluster() {RetryingCassandraClusterFactoryBean bean = new RetryingCassandraClusterFactoryBean();bean.setAddressTranslator(getAddressTranslator());bean.setAuthProvider(getAuthProvider());bean.setClusterBuilderConfigurer(getClusterBuilderConfigurer());bean.setClusterName(getClusterName());bean.setCompressionType(getCompressionType());bean.setContactPoints(getContactPoints());bean.setLoadBalancingPolicy(getLoadBalancingPolicy());bean.setMaxSchemaAgreementWaitSeconds(getMaxSchemaAgreementWaitSeconds());bean.setMetricsEnabled(getMetricsEnabled());bean.setNettyOptions(getNettyOptions());bean.setPoolingOptions(getPoolingOptions());bean.setPort(getPort());bean.setProtocolVersion(getProtocolVersion());bean.setQueryOptions(getQueryOptions());bean.setReconnectionPolicy(getReconnectionPolicy());bean.setRetryPolicy(getRetryPolicy());bean.setSpeculativeExecutionPolicy(getSpeculativeExecutionPolicy());bean.setSocketOptions(getSocketOptions());bean.setTimestampGenerator(getTimestampGenerator());bean.setKeyspaceCreations(getKeyspaceCreations());bean.setKeyspaceDrops(getKeyspaceDrops());bean.setStartupScripts(getStartupScripts());bean.setShutdownScripts(getShutdownScripts());return bean;}@Overrideprotected List getKeyspaceCreations() {final CreateKeyspaceSpecification specification =CreateKeyspaceSpecification.createKeyspace(keyspace).ifNotExists().with(KeyspaceOption.DURABLE_WRITES, true).withSimpleReplication();return List.of(specification);}@Overrideprotected String getContactPoints() {return hosts;} }那里沒有太多東西,但是如果Spring重試與Cassandra的初始連接,那么將會更少。 無論如何,讓我們將這一部分留出幾分鐘,集中討論本課程中的其他要點。
我創建ClusterConfig的最初原因是創建應用程序將使用的密鑰空間。 為此, getKeyspaceCreations被覆蓋。 當應用程序連接時,它將執行此方法中定義的查詢以創建鍵空間。
如果不需要這樣做,并且以其他某種方式創建了鍵空間,例如,在創建Cassandra容器時執行了腳本,則可以依靠Spring Boot的自動配置。 實際上,這允許通過application.properties中定義的屬性來配置整個應用application.properties而無需進行其他操作。 las,這本來不是。
由于我們已經定義了AbstractClusterConfiguration ,因此Spring Boot將在此區域中禁用其配置。 因此,我們需要通過重寫getContactPoints方法來手動定義contactPoints (我將其命名為變量hosts )。 最初,這僅在application.properties定義。 我意識到一旦開始出現以下錯誤,我需要進行此更改:
All host(s) tried for query failed (tried: localhost/127.0.0.1:9042 (com.datastax.driver.core.exceptions.TransportException: [localhost/127.0.0.1:9042] Cannot connect))在創建ClusterConfig之前,地址為cassandra而不是localhost 。
無需為集群配置其他任何屬性,因為在這種情況下,Spring的默認值就足夠了。
在這一點上我已經提到太多application.properties了,我應該向您展示其中的內容。
spring.data.cassandra.keyspace-name=mykeyspace spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS spring.data.cassandra.contact-points=cassandrakeyspace-name和contact-points已經彈出,因為它們與配置集群有關。 根據項目中的實體創建表需要進行schema-action 。 我們不需要在這里做任何其他事情,因為自動配置仍在該領域中工作。
contact-points值設置為cassandra的事實非常重要。 該域名源自提供給容器的名稱,在本例中為cassandra 。 因此,既可以使用cassandra也可以使用容器的實際IP。 域名肯定更容易,因為部署之間始終是靜態的。 只是為了驗證這一理論,您可以將cassandra容器的名稱更改為所需的名稱,只要您還在application.properties中進行了更改,它仍然可以連接。
返回到ClusterConfig代碼。 更確切地說,是cluster bean。 我再次粘貼了下面的代碼,以便于查看:
@Configuration public class ClusterConfig extends AbstractClusterConfiguration {// other stuff@Bean@Overridepublic CassandraClusterFactoryBean cluster() {RetryingCassandraClusterFactoryBean bean = new RetryingCassandraClusterFactoryBean();bean.setAddressTranslator(getAddressTranslator());bean.setAuthProvider(getAuthProvider());bean.setClusterBuilderConfigurer(getClusterBuilderConfigurer());bean.setClusterName(getClusterName());bean.setCompressionType(getCompressionType());bean.setContactPoints(getContactPoints());bean.setLoadBalancingPolicy(getLoadBalancingPolicy());bean.setMaxSchemaAgreementWaitSeconds(getMaxSchemaAgreementWaitSeconds());bean.setMetricsEnabled(getMetricsEnabled());bean.setNettyOptions(getNettyOptions());bean.setPoolingOptions(getPoolingOptions());bean.setPort(getPort());bean.setProtocolVersion(getProtocolVersion());bean.setQueryOptions(getQueryOptions());bean.setReconnectionPolicy(getReconnectionPolicy());bean.setRetryPolicy(getRetryPolicy());bean.setSpeculativeExecutionPolicy(getSpeculativeExecutionPolicy());bean.setSocketOptions(getSocketOptions());bean.setTimestampGenerator(getTimestampGenerator());bean.setKeyspaceCreations(getKeyspaceCreations());bean.setKeyspaceDrops(getKeyspaceDrops());bean.setStartupScripts(getStartupScripts());bean.setShutdownScripts(getShutdownScripts());return bean;}// other stuff }僅需要此代碼才能允許在初始Cassandra連接上重試。 這很煩人,但我無法提出另一個簡單的解決方案。 如果您有更好的選擇,請告訴我!
我所做的實際上很簡單,但是代碼本身并不是很好。 除了RetryingCassandraClusterFactoryBean (我自己的類)之外, cluster方法是AbstractClusterConfiguration重寫版本的副本。 原始函數改為使用CassandraClusterFactoryBean (Spring類)。
以下是RetryingCassandraClusterFactoryBean :
public class RetryingCassandraClusterFactoryBean extends CassandraClusterFactoryBean {private static final Logger LOG =LoggerFactory.getLogger(RetryingCassandraClusterFactoryBean.class);@Overridepublic void afterPropertiesSet() throws Exception {connect();}private void connect() throws Exception {try {super.afterPropertiesSet();} catch (TransportException | IllegalArgumentException | NoHostAvailableException e) {LOG.warn(e.getMessage());LOG.warn("Retrying connection in 10 seconds");sleep();connect();}}private void sleep() {try {Thread.sleep(10000);} catch (InterruptedException ignored) {}} }原始CassandraClusterFactoryBean的afterPropertiesSet方法采用其值,并通過最終委托給Datastax Java驅動程序來創建Cassandra集群的表示形式。 正如我在整個帖子中提到的。 如果無法建立連接,則將引發異常,如果未捕獲,將導致應用程序終止。 這就是上面代碼的重點。 它將afterPropertiesSet包裝在為可能引發的異常指定的try-catch塊中。
添加了sleep ,使Cassandra有一些時間可以真正啟動。 上一次嘗試失敗時,嘗試立即重新連接沒有任何意義。
使用此代碼,應用程序最終將連接到Cassandra。
在這一點上,我通常會向您顯示一些毫無意義的日志,以證明該應用程序可以正常工作,但是在這種情況下,它實際上并沒有帶來任何好處。 當您說以下命令時,請相信我:
mvn clean install && docker-compose up然后創建Spring應用程序映像,并旋轉兩個容器。
結論
我們已經看過如何將連接到Cassandra數據庫的Spring應用程序放入容器中。 一個用于應用程序,另一個用于Cassandra。 應用程序映像是從項目的代碼構建的,而Cassandra映像是從Docker Hub獲取的。 圖像名稱是cassandra只是為了確保沒有人忘記。 通常,將兩個容器連接在一起相對簡單,但是應用程序需要進行一些調整,以允許在連接到另一個容器中運行的Cassandra時重試。 這使代碼有些丑陋,但至少可以工作……由于本文中編寫了代碼,我現在有了另一個不需要在自己的機器上設置的應用程序。
這篇文章中使用的代碼可以在我的GitHub上找到 。
如果您發現此帖子有幫助,可以在Twitter上@LankyDanDev關注我,以了解我的新帖子。
鏈接到我的Spring Data Cassandra帖子
- Spring Data Cassandra入門
- 使用Spring Data Cassandra分離鍵空間
- 使用單個Spring Data CassandraTemplate的多個鍵空間
- 使用Spring Data Cassandra進行更復雜的建模
- Spring Data Cassandra中的啟動和關閉腳本
- Spring Data Cassandra的React流
- Spring Data Cassandra中自動配置隨附的管道
- 使用Datastax Java驅動程序與Cassandra進行交互
哇,我沒意識到我寫了那么多Cassandra帖子。
翻譯自: https://www.javacodegeeks.com/2018/09/spring-data-cassandra-application.html
cassandra可視化
總結
以上是生活随笔為你收集整理的cassandra可视化_容器化Spring Data Cassandra应用程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 奥迪 S7 Sportback 竞技限量
- 下一篇: 三星SDI将向与斯特兰蒂斯美国第二座合资