一、提供者与消费者
- 服务提供者: 一次业务中,被其他服务调用的服务
- 服务消费者: 一次业务中,调用其他服务的服务
二、Eureka原理分析
1、服务调度出现的问题
-
对于服务的访问地址(url),采用了硬编码的方式,当部署服务集群时,无法通过调度来选择
访问的对象。
-
由此会出现的问题
- 服务消费者如何获取服务提供者的地址信息?
- 如果有多个服务提供者,消费者该如何选择?
- 消费者如何得知提供者的健康状态?
2,Eureka如何解决服务调度出现的问题
-
1,eureka启动会创建一个注册中心。
-
2,每个服务启动时,会将自己的地址信息注册到eureka注册中心中。
-
3,当服务消费者需要时,会在eureka注册中心拉取需要的服务。
-
4,eureka注册中心会将所有符合的服务给到服务消费者。
-
5,服务消费者通过负载均衡选择合适的服务进行远程调用并获取响应数据。
-
6,eureka注册中心会监听提供者的健康状态,提供者每隔30秒会向eureka注册中心发起一次心跳,
一旦心跳停止(90秒内没有收到),eureka注册中心会清楚对应的服务信息。
三、搭建Eureka服务
1,导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2,注解开启注册服务
@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
3,配置信息
server:
port: 10086 # 服务端口
spring:
application:
name: eurekaserver # 服务名称
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka # 地址信息
register-with-eureka: true #是否把自己注册到Eureka注册中心
fetch-registry: true #是否从Eureka注册中心中拉取服务
- 服务名称与地址信息是为了在注册中心注册信息,所以Eureka注册中心也会注册自己的信息。
- 地址信息:注册中心的地址
- 服务名称:在注册中心注册的名称
四、服务注册
1、导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2、配置信息
spring:
application:
name: userservice # 服务名称
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka # 注册中心地址信息
3、注解
- 可以不加
@EnableDiscoveryClient
@EnableEurekaClient二选一即可,也可以一个都不加,建议都不加。
@MapperScan("cn.itcast.user.mapper")
@SpringBootApplication
@EnableDiscoveryClient
//@EnableEurekaClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
五、拉取服务
1,使用服务名称代替ip与端口号
String url = “http://localhost:8081/user/” + order.getUserId();
使用@LoadBalanced开启负载均衡后,它会将【localhost】识别成服务名,
所以会报错【找不到名为localhost的实例】String url = “http://userservice/user/” + order.getUserId();
所以一旦使用@LoadBalanced,就必须使用服务名代替ip+端口
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.发送http请求
/**
* 需要获取url路径与返回的数据类型
* url路径:类似浏览器,通过暴露的接口访问服务并获取响应的数据
* 返回的数据类型:因为服务响应的数据是JSON格式,通过一个具体的返回值类型可以转为对应格式
*/
//使用Eureka注册中心后,可以使用服务名称代替ip与端口,解除硬编码
//String url = "http://localhost:8081/user/" + order.getUserId();
String url = "http://userservice/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
// 3.封装数据
order.setUser(user);
// 4.返回
return order;
}
2,开启负载均衡
-
@LoadBalanced
-
必须开启负载均衡,不然服务消费者不知道选择哪一个服务提供者,会报错!
@Configuration
public class WebConfiguration {
/**
* 将RestTemplate注入spring容器
* @return
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}