在Kubernetes上使用Spring Boot實現Hazelcast分散式快取 – Piotr
Hazelcast是領先的記憶體資料網格(IMDG)解決方案。IMDG的主要思想是在群集內的許多節點之間分佈資料。因此,它似乎是在Kubernetes等雲平臺上執行的理想解決方案,在該平臺上,您可以輕鬆擴充套件或縮減多個正在執行的例項。由於Hazelcast是用Java編寫的,因此您可以使用標準庫輕鬆地將其與Java應用程式整合。Spring Boot可以簡化Hazelcast的入門。您也可以使用非官方的庫來為Hazelcast實現Spring Repositories模式-Spring Data Hazelcast。本文的主要目的是演示如何將Hazelcast嵌入到Spring Boot應用程式中以及如何在Kubernetes上將其作為多例項叢集執行。多虧了Spring Data Hazelcast,我們不必再去研究Hazelcast資料型別的細節了。儘管Spring Data Hazelcast並沒有提供許多高階功能,但對於入門來說還是非常好的。
帶有示例應用程式的原始碼通常可以在GitHub上獲得。它可以在這裡https://github.com/piomin/sample-hazelcast-spring-datagrid.git。您應該訪問模組employee-kubernetes-service。
架構
我們正在Kubernetes上執行單個Spring Boot應用程式的多個例項。每個應用程式公開用於HTTP API訪問的埠8080和用於Hazelcast群整合員發現的埠5701。Hazelcast例項被嵌入到Spring Boot應用程式中。我們正在Kubernetes上建立兩個服務。它們中的第一個專用於HTTP API訪問,而第二個則負責啟用Hazelcast例項之間的發現。HTTP API將用於發出一些測試請求,這些請求會將資料新增到群集並在其中查詢資料。讓我們繼續執行。
依賴關係
hazelcast-spring庫提供了Spring和Hazelcast之間的整合。Hazelcast庫的版本通過依賴管理與Spring Boot相關,因此我們只需要將Spring Boot的版本定義為最新的stable即可2.2.4.RELEASE。與該版本的Spring Boot相關的Hazelcast的當前版本為3.12.5。為了在Kubernetes上啟用Hazelcast成員發現,我們還需要包括hazelcast-kubernetes依賴項。其版本與核心庫無關。最新的版本2.0是因為我們仍然在使用Hazelcast 3我們宣佈版本專用於Hazelcast 4 1.5.2中hazelcast-kubernetes。為了簡化,我們還包括Spring Data Hazelcast和可選的Lombok。
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.4.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.hazelcast</groupId> <artifactId>spring-data-hazelcast</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-spring</artifactId> </dependency> <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-client</artifactId> </dependency> <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-kubernetes</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> |
啟用KUBERNETES發現
包括必需的依賴項後,已為我們的應用程式啟用了Hazelcast。我們唯一需要做的就是通過Kubernetes進行發現。該HazelcastInstancebean在上下文中已經可用,因此我們可以通過定義com.hazelcast.config.Configbean 來更改其配置。我們需要禁用預設情況下啟用的多播發現,並在網路配置中啟用Kubernetes發現,如下所示。Kubernetes配置需要設定Hazelcast部署的目標名稱空間及其服務名稱。
@Bean Config config() { Config config = new Config(); config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(false); config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false); config.getNetworkConfig().getJoin().getKubernetesConfig().setEnabled(true) .setProperty("namespace", "default") .setProperty("service-name", "hazelcast-service"); return config; } |
我們還必須hazelcast-service在port上定義Kubernetes服務5701。它指的是employee-service部署。
apiVersion: v1 kind: Service metadata: name: hazelcast-service spec: selector: app: employee-service ports: - name: hazelcast port: 5701 type: LoadBalancer |
這是我們的示例應用程式的Kubernetes部署和服務定義。我們為部署設定了三個副本。我們還將在容器外部公開兩個埠。
apiVersion: apps/v1 kind: Deployment metadata: name: employee-service labels: app: employee-service spec: replicas: 3 selector: matchLabels: app: employee-service template: metadata: labels: app: employee-service spec: containers: - name: employee-service image: piomin/employee-service ports: - name: http containerPort: 8080 - name: multicast containerPort: 5701 --- apiVersion: v1 kind: Service metadata: name: employee-service labels: app: employee-service spec: ports: - port: 8080 protocol: TCP selector: app: employee-service type: NodePort |
實際上,這是在Kubernetes上成功執行Hazelcast叢集所需要做的全部工作。在進行部署之前,讓我們看一下應用程式實現的詳細資訊。
實體
我們的應用非常簡單。它定義了一個模型物件,該物件儲存在Hazelcast群集中。這樣的類需要具有id –一個用Spring Data註釋的欄位@Id,並且應該實現Seriazable介面。
@Getter @Setter @EqualsAndHashCode @ToString public class Employee implements Serializable { @Id private Long id; @EqualsAndHashCode.Exclude private Integer personId; @EqualsAndHashCode.Exclude private String company; @EqualsAndHashCode.Exclude private String position; @EqualsAndHashCode.Exclude private int salary; } |
使用Spring Data Hazelcast,我們可以定義儲存庫,而無需使用任何查詢或特定於Hazelcast的API進行查詢。我們使用Spring Data定義的眾所周知的方法命名模式來構建find方法,如下所示。我們的儲存庫介面應該擴充套件HazelcastRepository。
public interface EmployeeRepository extends HazelcastRepository<Employee, Long> { Employee findByPersonId(Integer personId); List<Employee> findByCompany(String company); List<Employee> findByCompanyAndPosition(String company, String position); List<Employee> findBySalaryGreaterThan(int salary); } |
要啟用Spring Data Hazelcast儲存庫,我們應該使用註釋主類或配置類@EnableHazelcastRepositories。
@SpringBootApplication @EnableHazelcastRepositories public class EmployeeApplication { public static void main(String[] args) { SpringApplication.run(EmployeeApplication.class, args); } } |
最後,這是Spring控制器的實現。它允許我們呼叫儲存庫中定義的所有find方法,將新Employee物件新增到Hazelcast中並刪除現有物件。
@RestController @RequestMapping("/employees") public class EmployeeController { private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class); private EmployeeRepository repository; EmployeeController(EmployeeRepository repository) { this.repository = repository; } @GetMapping("/person/{id}") public Employee findByPersonId(@PathVariable("id") Integer personId) { logger.info("findByPersonId({})", personId); return repository.findByPersonId(personId); } @GetMapping("/company/{company}") public List<Employee> findByCompany(@PathVariable("company") String company) { logger.info(String.format("findByCompany({})", company)); return repository.findByCompany(company); } @GetMapping("/company/{company}/position/{position}") public List<Employee> findByCompanyAndPosition(@PathVariable("company") String company, @PathVariable("position") String position) { logger.info(String.format("findByCompany({}, {})", company, position)); return repository.findByCompanyAndPosition(company, position); } @GetMapping("/{id}") public Employee findById(@PathVariable("id") Long id) { logger.info("findById({})", id); return repository.findById(id).get(); } @GetMapping("/salary/{salary}") public List<Employee> findBySalaryGreaterThan(@PathVariable("salary") int salary) { logger.info(String.format("findBySalaryGreaterThan({})", salary)); return repository.findBySalaryGreaterThan(salary); } @PostMapping public Employee add(@RequestBody Employee emp) { logger.info("add({})", emp); return repository.save(emp); } @DeleteMapping("/{id}") public void delete(@PathVariable("id") Long id) { logger.info("delete({})", id); repository.deleteById(id); } } |
在MINIKUBE上執行
我們將在Minikube上測試示例應用程式。
$ minikube start --vm-driver=virtualbox |
該應用程式配置為可以與Skaffold和Jib Maven外掛一起執行。它們簡化了Minikube上的構建和部署過程。假設我們位於應用程式的根目錄中,我們只需要執行以下命令。Skaffold使用Maven自動構建我們的應用程式,基於Maven設定建立Docker映像,從k8s目錄中應用部署檔案,最後在Kubernetes上執行該應用程式。
$ skaffold dev |
從那以後,我們在deployment.yaml啟動的三個pod中宣告瞭我們的應用程式的三個例項。如果成功完成Hazelcast發現,您應該會看到Skaffold列印的Pod日誌片段。
詳細除錯圖片點選標題見原文。
相關文章
- Spring Boot整合Hazelcast實現叢集與分散式記憶體快取Spring BootAST分散式記憶體快取
- 分散式快取綜合指南:Kubernetes + Redis + Spring Boot分散式快取RedisSpring Boot
- Hazelcast簡單的分散式快取AST分散式快取
- 結合Hazelcast和Spring的分散式快取 - reflectoringASTSpring分散式快取
- Hazelcast JET在Spring Boot上執行ASTSpring Boot
- 使用Spring Boot實現分散式事務Spring Boot分散式
- 使用Kafka Streams和Spring Boot微服務中的分散式事務 - PiotrKafkaSpring Boot微服務分散式
- 使用Spring Boot和Kafka Streams實現基於SAGA模式的分散式事務原始碼教程 - PiotrSpring BootKafka模式分散式原始碼
- spring boot使用Jedis整合Redis實現快取(AOP)Spring BootRedis快取
- 使用Spring Boot和GraalVM在Knative上構建微服務 - piotrSpring BootLVM微服務
- WEB 應用快取解析以及使用 Redis 實現分散式快取Web快取Redis分散式
- 搞懂分散式技術14:Spring Boot使用註解整合Redis快取分散式Spring BootRedis快取
- 在 Kubernetes 上使用Spring Boot+ActiveMQSpring BootMQ
- Memcached 分散式快取實現原理分散式快取
- Spring Boot 整合 Redis 實現快取操作Spring BootRedis快取
- EVCache快取在 Spring Boot中的實戰快取Spring Boot
- Spring Boot Redis 實現分散式鎖,真香!!Spring BootRedis分散式
- 如何用REDIS實現分散式快取Redis分散式快取
- 雲上的分散式快取分散式快取
- 分散式快取NCache使用分散式快取
- 在Spring Boot快取API - Code FactorySpring Boot快取API
- Spring Boot 參考指南(Hazelcast)Spring BootAST
- 如何最簡單的實現分散式快取分散式快取
- 使用HazelCast實現Spring Config Server配置ASTSpringServer
- 分散式快取分散式快取
- 5、Spring Boot快取Spring Boot快取
- 在 Redis 上實現的分散式鎖Redis分散式
- Spring Boot:簡單使用EhCache快取框架Spring Boot快取框架
- redis分散式鎖-spring boot aop+自定義註解實現分散式鎖Redis分散式Spring Boot
- Spring Boot In Practice (1):Redis快取實戰Spring BootRedis快取
- 基於快取或zookeeper的分散式鎖實現快取分散式
- Guava Cache本地快取在 Spring Boot應用中的實踐Guava快取Spring Boot
- 10、Spring Boot分散式Spring Boot分散式
- Spring Boot中使用WebSocket總結(三):使用訊息佇列實現分散式WebSocketSpring BootWeb佇列分散式
- 使用Vue+Spring Boot實現Excel上傳VueSpring BootExcel
- 使用Spring Boot實現檔案上傳功能Spring Boot
- Spring Boot Cache Redis快取Spring BootRedis快取
- 分散式快取方案分散式快取