1.eureka注册和发现
1.1 eureka简介
Eureka是Netflix开发的服务发现框架,本身是一个基于REST的服务,主要用于定位运行在AWS域中的中间层服务,以达到负载均衡和中间层服务故障转移的目的。SpringCloud将它集成在其子项目spring-cloud-netflix中,以实现SpringCloud的服务发现功能。
Eureka由多个instance(服务实例)组成,这些服务实例可以分为两种:Eureka Server和Eureka Client。为了便于理解,我们将Eureka client再分为Service Provider和Service Consumer。
- Eureka Server 提供服务注册和发现
- Service Provider 服务提供方,将自身服务注册到Eureka,从而使服务消费方能够找到
- Service Consumer服务消费方,从Eureka获取注册服务列表,从而能够消费服务
1.2 eureka项目准备
pom.xml (关键依赖)
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR9</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.yml
spring:
application:
name: eureka-server
server:
port: 2001
eureka:
server:
enable-self-preservation: false
instance:
hostname: eureka1
client:
register-with-eureka: false
fetch-registry: false
主程序
@EnableEurekaServer
@SpringBootApplication
public class Sp05EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(Sp05EurekaApplication.class, args);
}
}
测试访问
说明:启动主程序后,会在注册中心发现自己,但无提供的服务
2.eureka特性
2.1 eureka四条运行机制
1. 注册
客户端会一次一次反复连接服务器进行注册,直到注册成功为止
2. 拉取
客户端每30秒拉取一次注册表,来刷新注册表
3. 心跳
客户端每30秒发送一次心跳,如果服务器连续三次收不到一个服务的心跳,会删除这个服务
4. 自我保护模式
- 由于网络不稳定,网络中断,15分钟内,85%服务器出现心跳异常,就会进入自我保护模式
- 在这种特殊情况下,所有服务都不删除
- 网络恢复正常后,可以自动退出保护模式
- 开发调试期间,可以禁用保护模式,避免影响测试
2.eureka详细特性
服务注册
- Eureka Client在第一次心跳时向Eureka Server注册
- 注册时会提供诸多自身元数据:主机名、端口、健康指标URL等
服务续约
- Eureka Client通过发送心跳进行续约
- 默认情况下每30秒发送一次心跳
- 如90秒内Eureka Server未收到续约,则进行服务剔除
服务下线
- Eureka Client优雅退出时会发送cancel命令
- Eureka Server收到cancel命令时会删除该节点
获取注册列表信息
- Eureka Client会缓存由Server获取的注册表信息
- Eureka Client会定期更新注册表信息【默认30秒】
- Eureka Client会处理注册表的合并等内容
Eureka的自我保护
- Eureka Server会自动更新续约更新阀值
- Eureka Server续约更新频率低于阈值则进入保护模式
- 自我保护模式下Eureka Server不会剔除任何注册信息
3. eureka高可用
3.1 服务调用
3.1.1.修改 hosts 文件,添加 eureka 域名映射
C:\Windows\System32\drivers\etc\hosts
添加内容:
127.0.0.1 eureka1
127.0.0.1 eureka2
3.1.2 service provider 服务提供者图示
3.1.3, 具体实现
修改 item-service、user-service、order-service,把微服务注册到 eureka 服务器
1.pom.xml 添加eureka依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2.application.yml 添加eureka注册配置
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka
3.主程序启用eureka客户端(略)
4.启动服务,在eureka中查看注册信息
3.2 集群互相调用
3.2.1. 集群前准备
说明:在edit config 编辑名字和环境配置后,再在service中复制一份修改端口后的到两台配置中心
3.2.2.集群结构图
3.2.3.集群测试
3.3.eureka 互相调用
3.3.1 添加两个服务器的 profile 配置文件
application-eureka1.yml
eureka:
instance:
hostname: eureka1
client:
register-with-eureka: true #profile的配置会覆盖公用配置
fetch-registry: true #profile的配置会覆盖公用配置
service-url:
defaultZone: http://eureka2:2002/eureka #eureka1启动时向eureka2注册
application-eureka2.yml
eureka:
instance:
hostname: eureka2
client:
register-with-eureka: true #profile的配置会覆盖公用配置
fetch-registry: true #profile的配置会覆盖公用配置
service-url:
defaultZone: http://eureka1:2001/eureka #eureka2启动时向eureka1注册
3.3.2 配置启动参数
--spring.profiles.active
和 --server.port
--spring.profiles.active=eureka1 --server.port=2001 #eureka1启动参数
--spring.profiles.active=eureka2 --server.port=2002 #eureka2启动参数
3.3.3,测试
4. fegin 调用服务
fegin 通过订单调用商品服务
4.1 调用流程图
说明:微服务应用中,ribbon 和 hystrix 总是同时出现,feign 整合了两者,并提供了声明式消费者客户端
4.2 实现步骤
1.在 sp04-orderservice 项目添加fegin依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.2.RELEASE</version>
</dependency>
2. 启动类添加注解: `@EnableFeignClients`
3.配置 写入调用代码接口
//ItemClient接口代码
@FeignClient(name = "item-service")
public interface ItemClient {
@GetMapping("/{orderId}")
JsonResult<List<Item>> getItems(@PathVariable String orderId);
@PostMapping("/decreaseNumber")
JsonResult<?> decreaseNumber(@RequestBody List<Item> items);
}
//UserClient接口代码
@FeignClient(name = "user-service")
public interface UserClient {
@GetMapping("/{userId}")
JsonResult<User> getUser(@PathVariable Integer userId);
@GetMapping("/{userId}/score") // ?score=1000
JsonResult<?> addScore(@PathVariable Integer userId,
@RequestParam("score") Integer score);
}
说明:接口的配置信息要包括以下部分
三个配置: 1. 调用哪个服务 2. 调用这个服务的哪个路径 3. 向这个路径提交什么参数 有可能出现错误: ..... not found: "item-service" 1. 服务没有启动,注册表中不存在 "item-service" 2. 服务已经启动,有注册信息,需要等待 30 秒刷新注册表
4.修改 OrderServiceImpl 完成远程的调用
@Slf4j
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/{orderId}")
public JsonResult<Order> getOrder(@PathVariable String orderId) {
log.info("get order, id="+orderId);
// TODO :远程调用商品,获取商品列表
// TODO :远程调用用户,获取用户数据
Order order = orderService.getOrder(orderId);
return JsonResult.ok(order);
}
@GetMapping("/add")
public JsonResult addOrder() {
//模拟post提交的数据
Order order = new Order();
order.setId("saf1234");
order.setUser(new User(8,null,null));
order.setItems(Arrays.asList(new Item[] {
new Item(1,"aaa",2),
new Item(2,"bbb",1),
new Item(3,"ccc",3),
new Item(4,"ddd",1),
new Item(5,"eee",5),
}));
orderService.addOrder(order);
return JsonResult.ok().msg("添加订单成功~~");
}
@GetMapping("/favicon.ico")
public void ico(){
}
}
4.3 测试
启动erueka,进行相应的调用,对其即
5.feign组件集合内容
fegin集合Ribbon,实现负载均衡和重试,feign集合Hystrix 断路实现服务降级
5.1 Ribbon重试
远程调用后台服务失败时,可以自动重试调用
- 失败:出现异常,一台服务器宕机,阻塞延迟超时
- 重试参数:
- MaxAutoRetries:单台服务器重试错误,默认值是0
- MaxAutoRetriesNextServer:更换服务器的次数,默认值是1
- ReadTimeOut: 等待响应的时间,默认1000,超过1s,进行一次重试
-
OkToRetryOnAllOperations: 是否对所有请求方式都重试,默认只对GET重试
- ConnectTimeout: 与后台服务器建立网络连接的超时时间
- 成功:返回参数
5.2 Ribbon 负载均衡
调用图示:
说明:fegin集成ribbon时默认采用轮询的负载均衡策略
5.3 Hystrix降级方法