The role of Eureka registration center
Eureka架构
Two problems with remote calls
服务的ip地址和端口号写死
: In a production environment服务的地址可能会随时发生变化
, if it is hard-coded, the code needs to be modified every time多实例问题
: In the case of high concurrency一个服务可以有多个实例形成一个集群
, if hard-coding is used at this time, only one instance address of the service can be accessed
In the Eureka architecture, microservice roles are divided intoEurekaServer和EurekaClient
two categories
EurekaServer(服务端)
: Can record service registration information (including service name and related instance address), monitor all service heartbeatsEurekaClient(客户端)
: Provider (service provider) and consumer (service consumer)
服务提供者与消费者
The service calling relationship includes service providers and service consumers. The definition of these two roles is not absolute because在不同业务中有些服务既可以是服务提供者也可以是服务消费者
服务提供者
: A service called by other microservices in a business (exposed interface to other microservices)服务消费者
: Calling the services of other microservices in a business (calling the interfaces provided by other microservices)
服务消费者
When initiating a remote call, determine the process of 服务提供者实例的ip地址和端口号
and pay attention服务消费者也需要把自己注册到Eureka服务端后才能使用其提供的服务
第一步服务注册
: After the service provider instance is started, it will register its own information toeureka-server(Eureka服务端)
第二步服务映射
:The Eureka server saves the mapping relationship between the names provided by all services and their corresponding service instance addresses into a Map collection.第三步服务发现
: The service consumer pulls the corresponding information from eureka based on the name of the service provider.一个服务可能有多个服务提供者所以最终会得到一个服务实例地址列表
第四步负载均衡
: The service consumer uses the load balancing algorithm to select an instance address from the instance address list and initiates a remote call.
How do service consumers perceive the health status of service providers?判断服务提供者是否宕机
第一步
: The service provider will send heartbeat requests to the EurekaServer server at regular intervals (default 30 seconds) to report its health status.第二步
:eureka updates the list information of the service provider by checking the heartbeat request. If the heartbeat is found to be abnormal, it will be removed from the service list, so that the service consumer can pull the latest information of the service provider.
Configure Eureka registration center
搭建注册中心(EurekaServer)
The first step is to create the sub-module: 在父工程cloud-demo中创建子模块eureka-server
, and then introduce the starter server dependency provided by SpringCloud for Eureka
<!--eureka服务端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
The second step is to write a startup class: Write a startup class in eureka-server模块
and add @EnableEurekaServer注解
, so that eureka-server服务
Has the function of being a registration center
- All microservices, including the eureka-server service, will go to the registration center to register their own information (including the name of the service and its related instance address)
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class);
}
}
The third step is to write the configuration file: Register its own service name and related instance address information to the eureka-server service ineureka-server服务
to facilitate communication with other eureka clusters Communication
server:
port: 10086 # 服务端口
spring:
application:
name: eureka-server # eureka的服务名称
# eureka服务将自己的信息注册到Eureka服务端
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
Step 4: Start the microservice and access http://localhost:10086/ in the browser
服务注册
The first step is to introduce dependencies: Introduce Eureka's client dependencies in the pom.xml file of user-service,order-service模块
spring-cloud-starter-netflix-eureka-client
<!--eureka客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
The second step of service registration: configure and in application.yml of user-service,order-service模块
自己的服务的名称
eureka-server服务的地址信息
spring:
application:
name: userservice # 服务名称
# userservice服务将自己的信息注册到Eureka服务端
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
spring:
application:
name: orderservice # 服务名称
# orderservice将自己的信息注册到Eureka服务端
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
The third step simulates multi-instance deployment: Copy a copy of the configuration of Startupuser-service实例
in IDEA, reset the Name, and modify the port number with the VM options-Dserver.port=8082
Step 4: View the services registered on the Eureka server and all related instances
service call
服务发现
The first step is to introduce dependencies: Service discovery and service registration are all encapsulated in Eureka's client dependencies. If the dependency has been introduced during registration, there is no need to introduce it again.
<!--eureka客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
The second step of service discovery: As long asorderservice服务
is registered in eureka-server服务
, you can pull the instance address list of userservice服务
- Add a load balancing annotation to the registered Bean in the startup class of
orderservice模块
RestTemplate
@LoadBalanced
- In the access path of remote call in
order-service模块
OrderService类中的queryOrderById方法
使用服务名(userservice)代替服务实例的ip和端口
- Spring will automatically help us obtain the corresponding instance address list from the Eureka server based on the service name
userservice
, and then use the load balancing algorithm to select an instance address and initiate a remote call
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.调用userservice服务远程查询User,使用服务的名称代替服务的IP地址和端口
//String url = "http://localhost:8081/user/" + order.getUserId();
String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
// 3.存入查询到的user对象
order.setUser(user);
// 4.返回
return order;
}