1. Introduction
technology | Version |
---|---|
Spring Cloud version | Hoxton.SR1 |
Spring Boot version | 2.2.2RELEASE |
Cloud Alibaba version | 2.1.0.RELEASE |
official address
git address: https://github.com/spring-projects/spring-boot/releases/
Spring Boot official website: https://spring.io/projects/spring-boot
git address: https://github.com/spring-projects/spring-cloud
Spring Boot official website: https://spring.io/projects/spring-cloud
Version of Spring Cloud
Spring Cloud is named after the London subway station in England, and releases an iterative version in the form of subway station names A-Z and so on. Spring Cloud is a comprehensive project composed of many sub-projects, and each sub-project has a different release rhythm. In order to manage the version dependencies between SpringCloud and each sub-project, a list is released, which includes the sub-project version corresponding to a SpringCloud version. In order to avoid confusion between the SpringCloud version number and the sub-project version number, the SpringCloud version uses a name instead of a version number. The names of these versions use the names of London subway stations, and correspond to the version time sequence according to the order of the alphabet. For example, Angel is the first version, and Brixton is the second version. When the release content of SpringCloud reaches a critical point or a major BUG is resolved, a "service releases" version, SRX version for short, will be released. For example, Greenwich.SR2 is the second SRX version of the Greenwich version released by SpringCloud.
1. The relationship between SpringBoot and SpringCloud
Website: https://spring.io/projects/spring-cloud#overview
View address for a more detailed version: https://start.spring.io/actuator/info
{ "git":{ "branch":"64b2829d7b37506fa4e7e5361462ac3ca91c1692", "commit":{ "id":"64b2829", "time":"2023-02-13T11:11:29Z" } }, "build":{ "version":"0.0.1-SNAPSHOT", "artifact":"start-site", "versions":{ "spring-boot":"3.0.2", "initializr":"0.20.0-SNAPSHOT" }, "name":"start.spring.io website", "time":"2023-02-13T11:12:37.946Z", "group":"io.spring.start" }, "bom-ranges":{ "codecentric-spring-boot-admin":{ "2.4.3":"Spring Boot >=2.3.0.M1 and <2.5.0-M1", "2.5.6":"Spring Boot >=2.5.0.M1 and <2.6.0-M1", "2.6.8":"Spring Boot >=2.6.0.M1 and <2.7.0-M1", "2.7.4":"Spring Boot >=2.7.0.M1 and <3.0.0-M1", "3.0.0-M4":"Spring Boot >=3.0.0-M1 and <3.1.0-M1" }, "solace-spring-boot":{ "1.1.0":"Spring Boot >=2.3.0.M1 and <2.6.0-M1", "1.2.2":"Spring Boot >=2.6.0.M1 and <3.0.0-M1" }, "solace-spring-cloud":{ "1.1.1":"Spring Boot >=2.3.0.M1 and <2.4.0-M1", "2.1.0":"Spring Boot >=2.4.0.M1 and <2.6.0-M1", "2.3.2":"Spring Boot >=2.6.0.M1 and <3.0.0-M1" }, "spring-cloud":{ "Hoxton.SR12":"Spring Boot >=2.2.0.RELEASE and <2.4.0.M1", "2020.0.6":"Spring Boot >=2.4.0.M1 and <2.6.0-M1", "2021.0.0-M1":"Spring Boot >=2.6.0-M1 and <2.6.0-M3", "2021.0.0-M3":"Spring Boot >=2.6.0-M3 and <2.6.0-RC1", "2021.0.0-RC1":"Spring Boot >=2.6.0-RC1 and <2.6.1", "2021.0.5":"Spring Boot >=2.6.1 and <3.0.0-M1", "2022.0.0-M1":"Spring Boot >=3.0.0-M1 and <3.0.0-M2", "2022.0.0-M2":"Spring Boot >=3.0.0-M2 and <3.0.0-M3", "2022.0.0-M3":"Spring Boot >=3.0.0-M3 and <3.0.0-M4", "2022.0.0-M4":"Spring Boot >=3.0.0-M4 and <3.0.0-M5", "2022.0.0-M5":"Spring Boot >=3.0.0-M5 and <3.0.0-RC1", "2022.0.0-RC1":"Spring Boot >=3.0.0-RC1 and <3.0.0-RC2", "2022.0.0-RC2":"Spring Boot >=3.0.0-RC2 and <3.0.0", "2022.0.1":"Spring Boot >=3.0.0 and <3.1.0-M1" }, "spring-cloud-azure":{ "4.6.0":"Spring Boot >=2.5.0.M1 and <3.0.0-M1", "5.0.0":"Spring Boot >=3.0.0-M1 and <3.1.0-M1" }, "spring-cloud-gcp":{ "2.0.11":"Spring Boot >=2.4.0-M1 and <2.6.0-M1", "3.4.3":"Spring Boot >=2.6.0-M1 and <3.0.0-M1", "4.0.0":"Spring Boot >=3.0.0-M1 and <3.1.0-M1" }, "spring-cloud-services":{ "2.3.0.RELEASE":"Spring Boot >=2.3.0.RELEASE and <2.4.0-M1", "2.4.1":"Spring Boot >=2.4.0-M1 and <2.5.0-M1", "3.3.0":"Spring Boot >=2.5.0-M1 and <2.6.0-M1", "3.4.0":"Spring Boot >=2.6.0-M1 and <2.7.0-M1", "3.5.0":"Spring Boot >=2.7.0-M1 and <3.0.0-M1", "4.0.0":"Spring Boot >=3.0.0 and <3.1.0-M1" }, "spring-shell":{ "2.1.6":"Spring Boot >=2.7.0 and <3.0.0-M1", "3.0.0":"Spring Boot >=3.0.0 and <3.1.0-M1" }, "vaadin":{ "14.9.6":"Spring Boot >=2.1.0.RELEASE and <2.6.0-M1", "23.2.15":"Spring Boot >=2.6.0-M1 and <2.7.0-M1", "23.3.5":"Spring Boot >=2.7.0-M1 and <2.8.0-M1" }, "wavefront":{ "2.0.2":"Spring Boot >=2.1.0.RELEASE and <2.4.0-M1", "2.1.1":"Spring Boot >=2.4.0-M1 and <2.5.0-M1", "2.2.2":"Spring Boot >=2.5.0-M1 and <2.7.0-M1", "2.3.4":"Spring Boot >=2.7.0-M1 and <3.0.0-M1", "3.0.1":"Spring Boot >=3.0.0-M1 and <3.1.0-M1" } }, "dependency-ranges":{ "okta":{ "1.4.0":"Spring Boot >=2.2.0.RELEASE and <2.4.0-M1", "1.5.1":"Spring Boot >=2.4.0-M1 and <2.4.1", "2.0.1":"Spring Boot >=2.4.1 and <2.5.0-M1", "2.1.6":"Spring Boot >=2.5.0-M1 and <3.0.0-M1", "3.0.2":"Spring Boot >=3.0.0-M1 and <3.1.0-M1", "managed":"Spring Boot >=3.1.0-M1" }, "mybatis":{ "2.1.4":"Spring Boot >=2.1.0.RELEASE and <2.5.0-M1", "2.2.2":"Spring Boot >=2.5.0-M1 and <2.7.0-M1", "2.3.0":"Spring Boot >=2.7.0-M1 and <3.0.0-M1", "3.0.0":"Spring Boot >=3.0.0-M1" }, "camel":{ "3.5.0":"Spring Boot >=2.3.0.M1 and <2.4.0-M1", "3.10.0":"Spring Boot >=2.4.0.M1 and <2.5.0-M1", "3.13.0":"Spring Boot >=2.5.0.M1 and <2.6.0-M1", "3.17.0":"Spring Boot >=2.6.0.M1 and <2.7.0-M1", "3.20.2":"Spring Boot >=2.7.0.M1 and <3.0.0-M1", "4.0.0-M1":"Spring Boot >=3.0.0-M1 and <3.1.0-M1" }, "picocli":{ "4.7.0":"Spring Boot >=2.5.0.RELEASE and <3.1.0-M1" }, "open-service-broker":{ "3.2.0":"Spring Boot >=2.3.0.M1 and <2.4.0-M1", "3.3.1":"Spring Boot >=2.4.0-M1 and <2.5.0-M1", "3.4.1":"Spring Boot >=2.5.0-M1 and <2.6.0-M1", "3.5.0":"Spring Boot >=2.6.0-M1 and <2.7.0-M1" } } }
2. Regarding the suspension/upgrade/replacement of various components of Cloud
Official website: https://cloud.spring.io/spring-cloud-static/Hoxton.SR1/reference/htmlsingle/
Official website: https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/htmlsingle/
Spring Cloud Chinese documentation: https://www.bookstack.cn/read/spring-cloud-docs/docs-index.md
After upgrade:
3. Code construction of microservice architecture (cloud-provider-payment8001)
3.1 pom file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-provider-payment8001</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.22</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
3.2 Change the yml file
server: port: 8001 spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.yyds.springcloud.entities
3.3 Main Boot
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); System.out.println("*******************PaymentMain8001 Start successfully********************"); } }
3.4 Business class
3.4.1 dao and mapper.xml
package com.yyds.springcloud.dao; import com.yyds.springcloud.entities.Payment; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @Mapper public interface PaymentDao { int create(Payment payment); Payment getPaymentById(@Param("id") Long id); }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.yyds.springcloud.dao.PaymentDao"> <resultMap id="BaseResultMap" type="payment"> <result column="id" property="id"/> <result column="serial" property="serial"/> </resultMap> <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id"> insert into payment (serial) value (#{serial}); </insert> <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap"> select * from payment where id = #{id} </select> </mapper>
3.4.2 service
package com.yyds.springcloud.service; import com.yyds.springcloud.entities.Payment; import org.apache.ibatis.annotations.Param; public interface PaymentService { int create(Payment payment); Payment getPaymentById(@Param("id") Long id); }
package com.yyds.springcloud.service.impl; import com.yyds.springcloud.dao.PaymentDao; import com.yyds.springcloud.entities.Payment; import com.yyds.springcloud.service.PaymentService; import org.springframework.stereotype.Service; import javax.annotation.Resource; @Service public class PaymentServiceImpl implements PaymentService { @Resource private PaymentDao paymentDao; @Override public int create(Payment payment) { return paymentDao.create(payment); } @Override public Payment getPaymentById(Long id) { return paymentDao.getPaymentById(id); } }
3.4.3 controller
package com.yyds.springcloud.controller; import com.yyds.springcloud.entities.CommonResult; import com.yyds.springcloud.entities.Payment; import com.yyds.springcloud.service.PaymentService; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/payment") @Slf4j public class PaymentController { @Resource private PaymentService paymentService; @PostMapping("/create") public CommonResult<Payment> create(@RequestBody Payment payment){ int result = paymentService.create(payment); if(result > 0){ return new CommonResult(200,"Inserted into the database successfully",result); }else { return new CommonResult(444,"Failed to insert into database",null); } } @GetMapping("/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){ Payment payment = paymentService.getPaymentById(id); log.info("*****search result:{}",payment); if (payment != null) { return new CommonResult(200,"search successful",payment); }else { return new CommonResult(200,"no correspondence id",null); } } }
3.4.4 Entity class
package com.yyds.springcloud.entities; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class CommonResult<T>{ private Integer code; private String message; private T data; public CommonResult(Integer code, String message) { this(code,message,null); } }
package com.yyds.springcloud.entities; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @AllArgsConstructor @NoArgsConstructor public class Payment implements Serializable { private Long id; private String serial; }
4,cloud-consumer-order80
RestTemplate provides a variety of convenient methods for accessing remote Http services. It is a simple and convenient way to access restful service template classes. It is a client template tool set provided by Spring for accessing Rest services.
- Official website address
https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html
- use
Using restTemplate to access the restful interface is very simple and rude. (url, requestMap, ResponseBean.class) These three parameters represent
REST request address, request parameters, and HTTP response conversion are converted into object types.
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-consumer-order80</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
- config configuration class
package com.yyds.springcloud.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ApplicationContextConfig { @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
package com.yyds.springcloud.controller; import com.yyds.springcloud.entities.CommonResult; import com.yyds.springcloud.entities.Payment; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/consumer/payment") @Slf4j public class OrderController { public static final String PAYMENT_URL = "http://localhost:8001"; @Resource private RestTemplate restTemplate; @GetMapping("/create") public CommonResult<Payment> create(Payment payment) { return restTemplate.postForObject(PAYMENT_URL +"/payment/create",payment,CommonResult.class); } @GetMapping("/get/{id}") public CommonResult<Payment> getPayment(@PathVariable("id") Long id) { return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class); } }
test
# calls between services http://localhost/consumer/payment/get/10 {"code":200,"message":"search successful","data":{"id":10,"serial":"11111"}} http://localhost/consumer/payment/create?serial=6666 {"code":200,"message":"Inserted into the database successfully","data":1}
engineering reconstruction
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-api-commons</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.1.0</version> </dependency> </dependencies> </project>
# Install cloud-api-commons locally mvn clean mvn install
Delete the entity class package in the two microservice modules, and then add the following configuration in the pom files of the two modules
<!--import your own defined api Universal package--> <dependency> <groupId>com.yyds</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
2. Eureka service registration and discovery
2.1 Introduction
2.1.1 What is Service Governance
Spring Cloud encapsulates the Eureka module developed by Netflix to implement service governance
In the traditional rpc remote call framework, it is more complicated to manage the dependencies between each service and the management, so it is necessary to use service governance to manage the dependencies between services and services, which can realize service calls, load balancing, Fault tolerance, etc., realize service discovery and registration.
2.2.2 What is service registration and discovery
Eureka adopts the design architecture of CS. Eureka Server is the server of the service registration function, which is the service registration center. Other microservices in the system use Eureka's client to connect to Eureka Server and maintain a heartbeat connection. In this way, system maintainers can use Eureka Server to monitor whether each microservice in the system is running normally.
In service registration and discovery, there is a registration center. When the server starts, it will register the information of the current server, such as the service address and mailing address, to the registration center in the form of an alias. The other party (consumer | service provider) uses the alias to obtain the actual service communication address from the registration center, and then realizes the local RPC call RPC remote call framework. The core design idea: lies in the registration center, because the use of the registration center Manage each service and a dependency between services (service governance concept). In any rpc remote framework, there will be a registration center (store service address related information (interface address))
2.2.3 Two components of Eureka
Eureka Server provides service registration service
After each microservice node is configured and started, it will be registered in EurekaServer, so that the service registry in EurekaServer will store the information of all available service nodes, and the information of service nodes can be seen directly in the interface.
EurekaClient accesses through the registration center
It is a Java client that simplifies the interaction with Eureka Server. The client also has a built-in load balancer that uses a round-robin load algorithm. After the application starts, a heartbeat will be sent to Eureka Server (the default period is 30 seconds). If Eureka Server does not receive a node's heartbeat within multiple heartbeat cycles, EurekaServer will remove the service node from the service registry (default 90 seconds)
2.2 Construction of stand-alone Eureka
Module name: cloud-eureka-server7001
2.2.1 The pom file is as follows
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-eureka-server7001</artifactId> <dependencies> <!--eureka-server--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <!-- import your own defined api common package, you can use Payment to pay Entity --> <dependency> <groupId>com.yyds</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--boot web actuator--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--General general configuration--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> </project>
2.2.2 yml file
server: port: 7001 eureka: instance: hostname: localhost #The instance name of the eureka server client: register-with-eureka: false #false means do not register yourself with the registry. fetch-registry: false #false means that my end is the registration center, and my responsibility is to maintain the service instance, and there is no need to retrieve the service service-url: defaultZone: http://localhost:7001/eureka
2.2.3 Main startup class
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication // add this note @EnableEurekaServer public class EurekaMain7001 { public static void main(String[] args) { SpringApplication.run(EurekaMain7001.class, args); System.out.println("************EurekaMain7001 Start successfully******************"); } }
Start the eureka test
http://localhost:7001/
2.2.4 Payment microservice cloud-provider-payment8001 register Eureka
EurekaClient cloud-provider-payment8001 will be registered into EurekaServer to become a service provider provider.
2.2.4.1 Change the pom file
<!--Add to eureka-client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
2.2.4.2 Write yml file
# Add the following configuration information eureka: client: service-url: defaultZone: http://localhost:7001/eureka/ register-with-eureka: true fetch-registry: true
2.2.4.3 Modify the main startup class
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication // add this note @EnableEurekaClient public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); System.out.println("*******************PaymentMain8001 Start successfully********************"); } }
Restart, refresh the Eureka page
2.2.5 Order microservice cloud-consumer-order80 register Eureka
EurekaClient cloud-consumer-order80 will be registered into EurekaServer to become a service consumer consumer.
2.2.5.1 Change the pom file
<!--Add to eureka-client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
2.2.5.2 Write yml file
server: port: 80 spring: application: name: cloud-order-service # Add the following configuration information eureka: client: service-url: defaultZone: http://localhost:7001/eureka/ register-with-eureka: true fetch-registry: true
2.2.5.3 Modify the main startup class
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class OrderMain80 { public static void main(String[] args) { SpringApplication.run(OrderMain80.class, args); System.out.println("***************OrderMain80 Start successfully********************"); } }
Restart, refresh the Eureka page
C:\Users\Undo\AppData\Roaming\Typora\typora-user-images\image-20230215231436950.png
2.3 Construction of cluster Eureka
If your registration center has only one, if it fails, the entire service environment will be unavailable, so you need to build a Eureka registration center cluster to achieve load balancing + fault tolerance.
2.3.1 New module cloud-eureka-server7002
Refer to cloud-eureka-server7001 to create a new module cloud-eureka-server7002
2.3.2 modify hosts
Add to the hosts file in the C:\Windows\System32\drivers\etc path
127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com
2.3.3 Modify the yml file
server: port: 7001 eureka: instance: hostname: eureka7001.com #The instance name of the eureka server client: register-with-eureka: false #false means do not register yourself with the registry. fetch-registry: false #false means that my end is the registration center, and my responsibility is to maintain the service instance, and there is no need to retrieve the service service-url: #The cluster points to other eureka defaultZone: http://eureka7002.com:7002/eureka/
server: port: 7002 eureka: instance: hostname: eureka7002.com #The instance name of the eureka server client: register-with-eureka: false #false means do not register yourself with the registry. fetch-registry: false #false means that my end is the registration center, and my responsibility is to maintain the service instance, and there is no need to retrieve the service service-url: #The cluster points to other eureka defaultZone: http://eureka7001.com:7001/eureka/
2.3.4 Modify the yml file of payment module and order module
server: port: 8001 spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/springcloud?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.yyds.springcloud.entities eureka: client: service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # cluster version register-with-eureka: true fetch-registry: true
server: port: 80 spring: application: name: cloud-order-service # Add the following configuration information eureka: client: service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # cluster version register-with-eureka: true # Whether to grab the existing registration information from EurekaServer, the default is true. Single node does not matter, the cluster must be set to true to use load balancing with ribbon fetch-registry: true
2.3.5 Testing
-
First start EurekaServer, 7001/7002 service
-
Then start the service provider provider, 8001
-
To start the consumer again, 80
-
Test port number: http://localhost/consumer/payment/get/1
2.3.6 Payment module service provider cluster configuration
Refer to cloud-provider-payment8001 to create a new cloud-provider-payment8002 module
And add the server.port attribute to the controller s of the two modules to facilitate testing
package com.yyds.springcloud.controller; import com.yyds.springcloud.entities.CommonResult; import com.yyds.springcloud.entities.Payment; import com.yyds.springcloud.service.PaymentService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @RestController @RequestMapping("/payment") @Slf4j public class PaymentController { @Resource private PaymentService paymentService; @Value("${server.port}") private String serverPort; @PostMapping("/create") public CommonResult<Payment> create(@RequestBody Payment payment){ int result = paymentService.create(payment); if(result > 0){ return new CommonResult(200,"Inserted into the database successfully,serverPort+" + serverPort ,result); }else { return new CommonResult(444,"Failed to insert into database",null); } } @GetMapping("/get/{id}") public CommonResult<Payment> getPaymentById(@PathVariable("id") Long id){ Payment payment = paymentService.getPaymentById(id); log.info("*****search result:{}",payment); if (payment != null) { return new CommonResult(200,"search successful,serverPort+" + serverPort,payment); }else { return new CommonResult(200,"no correspondence id",null); } } }
You can see the following page from Eureka
Visit http://localhost/consumer/payment/get/1
At this time, it is found that they are all accessing the 8001 service
{"code":200,"message":"search successful,serverPort+8001","data":{"id":1,"serial":"00001a"}}
Modify the order microservice interface
package com.yyds.springcloud.controller; import com.yyds.springcloud.entities.CommonResult; import com.yyds.springcloud.entities.Payment; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/consumer/payment") @Slf4j public class OrderController { // public static final String PAYMENT_URL = "http://localhost:8001"; public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE"; @Resource private RestTemplate restTemplate; @GetMapping("/create") public CommonResult<Payment> create(Payment payment) { return restTemplate.postForObject(PAYMENT_URL +"/payment/create",payment,CommonResult.class); } @GetMapping("/get/{id}") public CommonResult<Payment> getPayment(@PathVariable("id") Long id) { return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class); } }
At this time, when visiting http://localhost/consumer/payment/get/1, the following exception java.net.UnknownHostException: CLOUD-PAYMENT-SERVICE will be reported.
Need to modify the configuration class
package com.yyds.springcloud.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ApplicationContextConfig { @Bean @LoadBalanced // add this note public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
At this point, load balancing will be performed
{"code":200,"message":"search successful,serverPort+8002","data":{"id":1,"serial":"00001a"}} {"code":200,"message":"search successful,serverPort+8001","data":{"id":1,"serial":"00001a"}}
2.4 More usage
2.4.1 actuator microservice information improvement
Host name: service name modification
eureka: client: service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # cluster version register-with-eureka: true fetch-registry: true # add this configuration instance: instance-id: payment8001 eureka: client: service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # cluster version register-with-eureka: true fetch-registry: true # add this configuration instance: instance-id: payment8002
Access information has IP information prompt
eureka: client: service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # cluster version register-with-eureka: true fetch-registry: true instance: instance-id: payment8001 prefer-ip-address: true # show ip eureka: client: service-url: #defaultZone: http://localhost:7001/eureka defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # cluster version register-with-eureka: true fetch-registry: true instance: instance-id: payment8002 prefer-ip-address: true # show ip
2.4.2 Service discovery Discovery
For microservices registered in eureka, information about the service can be obtained through service discovery.
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication // add this note @EnableEurekaClient // add this note @EnableDiscoveryClient public class PaymentMain8001 { public static void main(String[] args) { SpringApplication.run(PaymentMain8001.class, args); System.out.println("*******************PaymentMain8001 Start successfully********************"); } }
@Resource private DiscoveryClient discoveryClient; @GetMapping("/discovery") public Object discovery(){ // service manifest list List<String> services = discoveryClient.getServices(); for (String service : services) { log.info("******************service:"+service); } List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE"); for (ServiceInstance instance : instances) { String host = instance.getHost(); String serviceId = instance.getServiceId(); URI uri = instance.getUri(); int port = instance.getPort(); log.info(serviceId + "\t" + host + "\t"+ port+ "\t" + uri ); } return this.discoveryClient; }
Test http://localhost:8001/payment/discovery
{"services":["cloud-payment-service","cloud-order-service"],"order":0}
******************service:cloud-payment-service ******************service:cloud-order-service CLOUD-PAYMENT-SERVICE 192.168.42.2 8002 http://192.168.42.2:8002 CLOUD-PAYMENT-SERVICE 192.168.42.2 8001 http://192.168.42.2:8001
2.4.3 Eureka self-protection
- What is Self-Defense Mode?
By default, if EurekaServer does not receive the heartbeat of a microservice instance within a certain period of time, EurekaServer will log off the instance (90 seconds by default). However, when a network partition failure occurs (delay, freeze, congestion), the normal communication between the microservice and EurekaServer may not be possible, and the above behavior may become very dangerous-because the microservice itself is actually healthy, and it is not at this time. This microservice should be unregistered. Eureka solves this problem through the "self-protection mode"-when the EurekaServer node loses too many clients in a short period of time (a network partition failure may occur), then this node will enter the self-protection mode.
- Why is there a Eureka self-protection mechanism?
In order to prevent EurekaClient from running normally, but in the case of a network failure with EurekaServer, EurekaServer will not immediately remove the EurekaClient service
In self-protection mode, Eureka Server will protect the information in the service registry and no longer log out any service instances. Its design philosophy is to rather keep wrong service registration information than blindly unregister any service instance that may be healthy.
- no self-protection
eureka: instance: hostname: eureka7001.com #The instance name of the eureka server client: register-with-eureka: false #false means do not register yourself with the registry. fetch-registry: false #false means that my end is the registration center, and my responsibility is to maintain the service instance, and there is no need to retrieve the service service-url: #The cluster points to other eureka defaultZone: http://eureka7002.com:7002/eureka/ #Standalone is 7001 itself # defaultZone: http://localhost:7001/eureka server: #Turn off the self-protection mechanism to ensure that unavailable services are kicked out in time enable-self-preservation: false eviction-interval-timer-in-ms: 2000
server: port: 8001 ###service name (service registered to eureka name) spring: application: name: cloud-provider-payment eureka: client: #The service provider provider is registered in the eureka service list service-url: register-with-eureka: true fetch-registry: true # cluster version #defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka # singleton version defaultZone: http://eureka7001.com:7001/eureka #Heartbeat detection and renewal time #Set smaller during development to ensure that the registration center can remove the service even after the service is closed instance: #The time interval for the Eureka client to send heartbeats to the server, in seconds (the default is 30 seconds) lease-renewal-interval-in-seconds: 1 #The Eureka server waits for the upper limit of the time after receiving the last heartbeat, in seconds (the default is 90 seconds), and the timeout will remove the service lease-expiration-duration-in-seconds: 2
After closing 8001, Eureka will remove it.
2.4.4 Eureka stopped updating
https://github.com/Netflix/eureka/wiki
C:\Users\Undo\AppData\Roaming\Typora\typora-user-images\image-20230216223537190.png
3. Zookeeper service registration and discovery
-
zookeeper is a distributed coordination tool that can realize the registration center function
-
The zookeeper server replaces the Eureka server, and zk serves as the service registry
3.1 Service provider cloud-provider-payment8004
3.1.1 pom file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-provider-payment8004</artifactId> <dependencies> <!--to integrate zk client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <!--First exclude the built-in zookeeper3.5.3--> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <!--Add your own installed zookeeper3.4.6 cluster--> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> <!-- Exclude log dependencies, otherwise log conflicts will occur --> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
3.1.2 yml file
server: port: 8004 spring: application: name: cloud-payment-service cloud: zookeeper: connect-string: 192.168.42.101:2181,192.168.42.102:2181,192.168.42.103:2181
3.1.3 Main startup class
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication //This annotation is used to register services when using consul or zookeeper as a registry @EnableDiscoveryClient public class PaymentMain8004 { public static void main(String[] args) { SpringApplication.run(PaymentMain8004.class, args); System.out.println("*******************PaymentMain8004 Start successfully********************"); } }
3.1.4 Business class
package com.yyds.springcloud.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/payment") @Slf4j public class PaymentController { @Value("${server.port}") private String serverPort; @GetMapping("/zk") public String paymentZk(){ return "spring cloud with zk:" + serverPort + "\t" + System.currentTimeMillis(); } }
3.1.5 Testing
http://localhost:8004/payment/zk spring cloud with zk:8004 1676560104626 # Check in zk and find that it has been registered [zk: localhost:2181(CONNECTED) 3] ls /services [cloud-payment-service] [zk: localhost:2181(CONNECTED) 6] get /services/cloud-payment-service/25db342b-6426-47f5-9bc6-6c084a245723 { "name":"cloud-payment-service", "id":"25db342b-6426-47f5-9bc6-6c084a245723", "address":"DESKTOP-6CM5A7S", "port":8004, "sslPort":null, "payload":{ "@class":"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance", "id":"application-1", "name":"cloud-payment-service", "metadata":{ } }, "registrationTimeUTC":1676560096304, "serviceType":"DYNAMIC", "uriSpec":{ "parts":[ { "value":"scheme", "variable":true }, { "value":"://", "variable":false }, { "value":"address", "variable":true }, { "value":":", "variable":false }, { "value":"port", "variable":true } ] } }
Note: When killing the registered service, zk will delete the service information.
3.2 Service provider cloud-consumerzk-order80
3.2.1 pom file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-consumerzk-order80</artifactId> <dependencies> <!--to integrate zk client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId> <!--First exclude the built-in zookeeper3.5.3--> <exclusions> <exclusion> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </exclusion> </exclusions> </dependency> <!--Add to zookeeper3.4.6 Version--> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> <!-- Exclude log dependencies, otherwise log conflicts will occur --> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
3.2.2 yml file
server: port: 80 spring: application: name: cloud-consumer-order cloud: zookeeper: connect-string: 192.168.42.101:2181,192.168.42.102:2181,192.168.42.103:2181
3.2.3 Main Boot
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ZkOrderMain80 { public static void main(String[] args) { SpringApplication.run(ZkOrderMain80.class, args); System.out.println("***************ZkOrderMain80 Start successfully********************"); } }
3.2.4 Business class
package com.yyds.springcloud.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/consumer/zk") @Slf4j public class OrderController { public static final String PAYMENT_URL = "http://cloud-payment-service"; @Resource private RestTemplate restTemplate; @GetMapping() public String paymentInfo() { return restTemplate.getForObject(PAYMENT_URL +"/payment/zk",String.class); } }
package com.yyds.springcloud.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class ApplicationContextConfig { @Bean @LoadBalanced public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
3.2.5 Testing
http://localhost/consumer/zk spring cloud with zk:8004 1676562116384 [zk: localhost:2181(CONNECTED) 28] ls /services [cloud-payment-service, cloud-consumer-order] [zk: localhost:2181(CONNECTED) 30] get /services/cloud-consumer-order/8d13f36d-0697-4e98-a7f5-8d16169b4588 { "name":"cloud-consumer-order", "id":"8d13f36d-0697-4e98-a7f5-8d16169b4588", "address":"DESKTOP-6CM5A7S", "port":80, "sslPort":null, "payload":{ "@class":"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance", "id":"application-1", "name":"cloud-consumer-order", "metadata":{ } }, "registrationTimeUTC":1676561841585, "serviceType":"DYNAMIC", "uriSpec":{ "parts":[ { "value":"scheme", "variable":true }, { "value":"://", "variable":false }, { "value":"address", "variable":true }, { "value":":", "variable":false }, { "value":"port", "variable":true } ] } }
4. Consul service registration and discovery
Consul is an open source distributed service discovery and configuration management system developed by HashiCorp in Go language.
Provides functions such as service governance, configuration center, and control bus in the microservice system. Each of these functions can be used individually as needed, or they can be used together to build a full range of service grids. In short, Consul provides a complete service grid solution.
Official website address: https://www.consul.io/intro/index.html
Download address: https://www.consul.io/downloads.html
Chinese documentation: https://www.springcloud.cc/spring-cloud-consul.html
4.1 Consul installation
The installation is relatively simple, directly unzip, only one exe file
consul --version # start up consul agent -dev It can be accessed through the following address Consul 's homepage: http://localhost:8500
4.2 Payment service cloud-providerconsul-payment8006
4.2.1 pom file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-providerconsul-payment8006</artifactId> <dependencies> <!--to integrate consul--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
4.2.2 yml file
server: port: 8006 spring: application: name: cloud-provider-payment cloud: consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name} heartbeat: enabled: true
4.2.3 Main startup class
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @SpringBootApplication //This annotation is used to register services when using consul or zookeeper as a registry @EnableDiscoveryClient public class ConsulPaymentMain8006 { public static void main(String[] args) { SpringApplication.run(ConsulPaymentMain8006.class, args); System.out.println("*******************ConsulPaymentMain8006 Start successfully********************"); } }
4.2.4 Business class
package com.yyds.springcloud.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/payment") @Slf4j public class PaymentController { @Value("${server.port}") private String serverPort; @GetMapping("/consul") public String paymentZk(){ return "spring cloud with consul:" + serverPort + "\t" + System.currentTimeMillis(); } }
4.2.5 Testing
http://localhost:8006/payment/consul spring cloud with consul:8006 1676563822227
4.3 service consumer cloud-consumerconsul-order80
4.3.1 pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yyds</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>cloud-consumerconsul-order80</artifactId> <dependencies> <!--to integrate consul--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
4.3.2 yml
server: port: 80 spring: application: name: cloud-consumer-order cloud: consul: host: localhost port: 8500 discovery: service-name: ${spring.application.name} heartbeat: enabled: true
4.3.3 Master Boot
package com.yyds.springcloud; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ConsulOrderMain80 { public static void main(String[] args) { SpringApplication.run(ConsulOrderMain80.class, args); System.out.println("***************ConsulOrderMain80 Start successfully********************"); } }
4.3.4 Business class
package com.yyds.springcloud.controller; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.annotation.Resource; @RestController @RequestMapping("/consumer/consul") @Slf4j public class OrderConsulController { public static final String PAYMENT_URL = "http://cloud-provider-payment"; @Resource private RestTemplate restTemplate; @GetMapping() public String paymentInfo() { return restTemplate.getForObject(PAYMENT_URL +"/payment/consul",String.class); } }
4.3.5 Testing
http://localhost/consumer/consul spring cloud with consul:8006 1676564785406