Table of contents
- 1. Eureka service registration and discovery
- 2. Zookeeper service registration and discovery
- 3. Consul service registration and discovery
- Four, the similarities and differences of the three registration centers
1. Eureka service registration and discovery
EurekaBasics
Service Governance
service registration
Eureka components
Single follow Eureka build
IDEA generates EurekaServer service registration center
1. Create a module
2. Add dependency
Dependency comparison
<dependencies>
<!-- eureka-server -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- 引用自己定义的api通用包,可以使用Payment支付Entity -->
<dependency>
<groupId>com.zhao.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</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>
3. Write yml file
server:
port: 7001
eureka:
instance:
hostname: localhost #eureka服务端的实例名称
client:
#false表示不向注册中心注册自己(想注册也可以,不过没必要)
register-with-eureka: false
#false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检索服务
fetch-registry: false
service-url:
#设置与eurekaServer交互的地址查询服务和注册服务都需要依赖这个地址
defaultZone: http://${
eureka.instance.hostname}:${
server.port}/eureka/
4. Main startup class
@SpringBootApplication
@EnableEurekaServer
public class EurekaMain7001 {
public static void main(String[] args) {
SpringApplication.run(EurekaMain7001.class);
}
}
5. Test
access:http://localhost:7001/
Register EurekaClient 8001 into EurekaServer to become a service provider provider
Client dependency comparison:
1. Introduce dependencies
<!-- eureka-client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. Modify yml and add:
eureka:
client:
#true表示向注册中心注册自己,默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://localhost:7001/eureka
3. Modify the startup class
@SpringBootApplication
@EnableEurekaClient
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class);
}
}
4. Start the project and register successfully!
Register EurekaClient 80 into EurekaServer to become a service consumer consumer
Step i is the same as registering EurekaClient 8001 into EurekaServer to become a service provider provider ! ! !
Cluster Eureka Construction
Build a Eureka registry cluster to achieve load balancing + fault tolerance.
Eureka cluster: mutual registration, mutual watch
Build a EurekaServer cluster environment
- Refer to cloud-eureka-server7001 to create new cloud-eureka-server7002
- Modify mapping configuration
C:\Windows\System32\drivers\etc
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
127.0.0.1 eureka7003.com
- Modify the yml file of 7001
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com #eureka服务端的实例名称
client:
register-with-eureka: false
fetch-registry: false
service-url:
# 单机
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
#集群版 相互注册,相互守望
defaultZone: http://eureka7002.com:7002/eureka/
- Modify the yml file of 7002
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com #eureka服务端的实例名称
client:
register-with-eureka: false
fetch-registry: false
service-url:
#集群版 相互注册,相互守望
defaultZone: http://eureka7001.com:7001/eureka/ #相互注册,相互守望
- Startup project
Publish the payment service 8001 and order service 80 microservices to the cluster configuration
- Change the defaultZone in the yml files of the two projects to:
#集群版
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
- start four projects
The cluster is built! !
Construct payment service provider cluster environment
- Create a new 8002 according to 8001 (except for the port number and the main configuration class that need to be changed in the yml file, other directly copy 8001, the application name in the yml file does not need to be changed, because it is a cluster, so the application name needs to be consistent)
- Add in the PaymentController of all providers: (this @Value is a spring annotation)
- Start all services separately for testing
load balancing
- Modify the consumer's OrderController and change the hard-coded url to the service name:
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
- Add it to the restTemplate method in the consumer's ApplicationContextConfig to
@LoadBalanced
enable the load balancing function.
Restart the test!
Actuator microservice information improvement
Modify the yml of 8001 service and 8002 service
eureka:
client:
#true表示向注册中心注册自己,默认为true
register-with-eureka: true
#是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用负载均衡
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
# 新增
instance:
instance-id: payment8001
prefer-ip-address: true
# 8002 yml
instance:
instance-id: payment8002
prefer-ip-address: true
Service Discovery
For microservices registered in eureka, information about the service can be obtained through service discovery.
- Modify the controller that provides the service
@Resource
private DiscoveryClient discoveryClient;
@GetMapping("/payment/discovery")
public Object discovery(){
List<String> services = discoveryClient.getServices();
for (String element : services) {
log.info("*******element:"+element);
}
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance : instances) {
log.info(instance.getServiceId()+"\t"+instance.getHost()+"\t"+instance.getPort()+"\t"+instance.getUri());
}
return discoveryClient;
}
- Add annotations to the main startup class
@EnableDiscoveryClient
- test
Eureka self-protection
Prohibition of self-protection mechanisms
The yml file of cloud-eureka-server7001:
eureka:
......
server:
#关闭自我保护,默认为true
enable-self-preservation: false
#心跳的间隔时间,单位毫秒
eviction-interval-timer-in-ms: 2000
yml file of cloud-provider-payment8001:
#Eureka客户端向服务端发送心跳的时间间隔,单位秒(默认30秒)
lease-renewal-interval-in-seconds: 1
#Eureka服务端在收到最后一次心跳后等待的时间上限,单位秒(默认90秒),超时剔除服务
lease-expiration-duration-in-seconds: 2
2. Zookeeper service registration and discovery
Registry Zookeeper
Deploy the Zookeeper service in the server, here use docker deployment
#拉取Zookeeper镜像
docker pull zookeeper
#启动Zookeeper
docker run -d --name zk01 -p 2181:2181 --restart always zookeeper
turn off firewall
systemctl stop firewalld
systemctl status firewalld
service providers
1. Create a new module
2. Modify the POM
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
3. Write yml
server:
port: 8004
spring:
application:
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: xxxxxx
4. Master Boot
@SpringBootApplication
@EnableDiscoveryClient // //该注解用于向使用consul或者Zookeeper作为注册中心时注册服务
public class PaymentMain8004 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8004.class);
}
}
5.controller
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/zk")
public String paymentzk(){
return "springcloud with zookeeper: " +serverPort+"\t"+ UUID.randomUUID().toString();
}
}
6. Start the zk container
7. Start the test
8. Enter the Zookeeper container (successfully registered into the registration center)
json tool: https://tool.lu/json/
Is the service node a temporary node or a persistent node?
Zookeeper also has a heartbeat mechanism. If there is no heartbeat to return within a certain period of time, Zookeeper will remove the service node. So the service nodes on Zookeeper are temporary nodes.
service providers
1. Create a new consumer module cloud-consumerzk-order80.
2. Pom and yml copy 8004 directly. (The port number in yml is changed to 80, the application name is changed to cloud-consumer-order, and the others are the same)
3. The main startup class. (same as 8004)
4. Create a configuration class
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
6.controller
@RestController
@Slf4j
public class OrderZKController {
public static final String INVOKE_URL = "http://cloud-provider-payment";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/zk")
public String paymentInfo(){
String result = restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class);
return result;
}
}
7. Start the project
3. Consul service registration and discovery
Consul official website: https://www.consul.io/
Consul Chinese documentation: https://www.springcloud.cc/spring-cloud-consul.html
Introduction to Consul
Consul is a service networking solution that enables teams to manage secure networking between services and across multi-cloud environments and runtimes. Consul provides service discovery, identity-based authorization, L7 traffic management, and service-to-service encryption.
- Service discovery: Consul clients can register services, such as api or mysql, and other clients can use Consul to discover providers for a given service. Using DNS or HTTP, applications can easily find the services they depend on.
- Health Checks: Consul clients can provide any number of health checks, which can be related to a given service ("is the web server returning a 200OK") or to the local node ("memory utilization is below 90%"). Operators can use this information to monitor the health of the cluster, and service discovery components can use this information to route traffic away from unhealthy hosts.
- KV store: Applications can use Consul's hierarchical key/value store for a variety of purposes, including dynamic configuration, feature flagging, coordination, leader election, and more. Simple HTTP API makes it easy to use.
- Secure service communication: Consul can generate and distribute TLS certificates for services to establish mutual TLS connections. Intents can be used to define which services are allowed to communicate. Segmentation of services can be easily managed with intents that can change in real time, instead of complex network topologies and static firewall rules.
- Multiple data centers: Consul supports multiple data centers out of the box. This means that users of Consul don't have to worry about building additional abstraction layers to scale to multiple regions.
Consul is designed to be friendly to the DevOps community and application developers, making it ideal for modern, flexible infrastructure.
Install and run Consul
Docker install Consul
#拉取consul镜像
docker pull consul
#启动consul
docker run -d -p 8500:8500/tcp --name myConsul consul agent -server -ui -bootstrap-expect=1 -client=0.0.0.0
test access
service providers
1. Create a new module
2. Modify the POM, the others are the same as before, replace zookeeper as follows
<!--SpringCloud consul-server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
3. Write YML
server:
port: 8006
spring:
application:
name: consul-provider-payment
cloud:
consul:
host: 139.196.177.161 #用linux的ip地址(consul在本机就填localhost)
port: 8500
discovery:
service-name: ${
spring.application.name}
prefer-ip-address: true
register-health-check: false
4. Master Boot
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class);
}
}
5. Business class
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/consul")
public String paymentConsul(){
return "springcloud with zookeeper: " +serverPort+"\t"+ UUID.randomUUID().toString();
}
}
6. Test start
service consumer
1. Create a new module cloud-consumer-consul-order80
- pom (same as 8006)
3.yml (the port number is 80, the application name is consul-consumer-order, the others are the same as 8006)
server:
port: 80
spring:
application:
name: consul-consumer-order
cloud:
consul:
host: 139.196.177.161 #用linux的ip地址(consul在本机就填localhost)
port: 8500
discovery:
service-name: ${spring.application.name}
prefer-ip-address: true
register-health-check: false
4. Main startup class (same as 8006)
@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class);
}
}
5.config (same as zk consumer)
6.controller
@RestController
@Slf4j
public class OrderConsulController {
public static final String INVOKE_URL = "http://consul-provider-payment";
@Resource
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/consul")
public String paymentInfo(){
String result = restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);
return result;
}
}
7. Test
Four, the similarities and differences of the three registration centers
AP:
CP: