您现在的位置是:首页 >技术教程 >【SpringCloud组件——Eureka】网站首页技术教程
【SpringCloud组件——Eureka】
前置准备:
分别提供订单系统(OrderService)和用户系统(UserService)。订单系统主要负责订单相关信息的处理,用户系统主要负责用户相关信息的处理。
一、微服务当中的提供者和消费者
1.1、概念
服务提供者:
一次业务中,被其它微服务调用的服务。(提供接口给其他微服务)
服务消费者:
一次业务中,调用其它微服务的服务。(调用其它微服务提供的接口)
思考:服务A调用服务B,服务B又调用服务C,那么服务B是什么角色?
A调用B时,B是提供者;B调用C时,B又是消费者。这就说明,B的角色是相对的,即相对谁而言决定B的角色。在这个案例当中,B既是消费者又是提供者。
1.2、案例讲解
访问订单系统,查询订单编号为XXX的订单,并返回订单当中的用户信息。我们知道每张订单都会记录该订单支付者的信息,一般是支付者账号信息。根据该信息调用用户系统当中的根据账户查询用户的接口即可。
1.2.1、订单系统:
①、订单查询接口
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
// 根据id查询订单并返回
return orderService.queryOrderById(orderId);
}
}
②、生成远程调用实例对象
//在SpringBoot启动类当中添加如下代码
@Bean
@LoadBalanced//负载均衡
public RestTemplate restTemplatest(){
return new RestTemplate();
}
③、订单查询服务实现类
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById2(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.利用RestTemplate发送http请求,查询用户
//2.1、url路径
String url = "http://localhost:8088/user/" + order.getUserId();
//2.2、发送http请求,实现远程调用
User user = restTemplate.getForObject(url, User.class);
//3.封装user到order
order.setUser(user);
// 4.返回
return order;
}
1.2.2、用户系统:
①、用户查询接口
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
}
②、用户查询实现类
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id) {
return userMapper.findById(id);
}
}
二、Eureka注册中心
我们先分析上述代码远程调用的弊端:
①、userService服务为了应对高并发,可能存在多个实例
②、userService服务可能有不同的环境配置,例如开发环境端口为8088,测试环境为8089等
③、在多实例情况下,orderService如何选择userService?
④、在多实例情况下,orderService如何知道选择的实例的健康状态?
这些弊端就足以说明我们上述硬编码方式的弊端了-》不够灵活。
2.1、Eureka的作用
当user-service:8081、user-service:8082、user-service:8083启动时会向Eureka注册中心进行登记,Eureka则会记录该服务的这些信息,同理,order-Service也会注册到Eureka当中,当orderService需要远程调用userService时,此时就会向Eureka获取该服务的注册列表,拿到注册列表后根据负载均衡原理挑选出一个服务实例进行调用。还有一个问题没有解决,Eureka如何知道某服务实例的健康状态呢?当服务实例注册到Eureka之后,会每隔30s向Eureka发送一个心跳续约,告知Eureka本实例的状态,当不发送时,Eureka则认为该实例挂掉了,则会从服务列表剔除该实例,下次当消费者再次获取实例列表时将不再推送该实例信息。智能吧?在Nacos面前这就是弟弟~
总结:
2.2、搭建Eureka注册中心
2.2.1、创建独立的服务
2.2.2、导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
2.2.3、启动类添加注解
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class,args);
}
}
2.2.4、编写配置文件
server:
port: 10086 #服务端口
spring:
application:
name: eurekaserver #服务名称
eureka:
client:
service-url: #eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
2.3、 服务注册
2.3.1、在微服务模块导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.3.2、在微服务配置文件添加配置
spring:
application:
name: XXXXservice
eureka:
client:
service-url: #eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
2.4、 基于Eureka远程调用
2.3完成了服务注册,下面进行后续的步骤:
2.4.1、服务列表拉取
修改访问的url路径,用服务名代替ip、端口:
String url = "http://userservice/user/" + order.getUserId();
当我们启动多个实例后 ,获取到的访问地址是该服务的实例列表,经过负载均衡算法处理过后会得到准确的访问地址。
2.4.2、做负载均衡
@Bean
@LoadBalanced//负载均衡
public RestTemplate restTemplatest(){
return new RestTemplate();
}