1 Eureka简介和组成
Eureka是Netflix公司开发的服务发现框架,SpringCloud将它集成在自己的子项目 spring-cloud-netflix中,实现SpringCloud的服务发现功能。Eureka包含两个组件: Eureka Server和Eureka Client。
- Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
- Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也 就别一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会 向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有 接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90 秒)。
- Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活 性和可伸缩性。
2. Eureka实战
(1)引入依赖 父工程pom.xml定义SpringCloud版本
代码语言:javascript复制<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.M9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
子服务模块pom.xml引入eureka-server
代码语言:javascript复制<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐eureka‐ server</artifactId>
</dependency>//这里无需指定版本号,因为我们在父pom里已经进行了版本控制
</dependencies>
代码语言:javascript复制服务端yml配置
server:
port: 6868
eureka:
client:
register-with-eureka: false #是否注册到eureka服务器上选择false,因为这是一个服务器模块
fetch-registry: false #是否拿到注册
service-url:
defaultZone: http://127.0.0.1:${server.port}/eureka/
客户端yml配置
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:6868/eureka/
instance:
prefer-ip-address: true #部署导线上时,可以使模块之间跨域访问
Feign实现服务间的调用
Feign是简化Java HTTP客户端开发的工具 (java-to-httpclient-binder),它的灵感 来自于Retrofit、JAXRS-2.0和WebSocket。 Feign的初衷是降低统一绑定Denominator到 HTTP API的复杂度,不区分是否为restful。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。
Feign快速体验 举例qa项目调用base项目
(1)qa模块(客户端模块)添加Feign调用依赖
代码语言:javascript复制<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
qa的启动类上增加两个注解
代码语言:javascript复制@SpringBootApplication//原有-springboot启动类
@EnableEurekaClient//原有-标明这里是一个服务组件并注册到Eureka
@EnableDiscoveryClient//增加-使的qa服务可以去发现其他服务
@EnableFeignClients//增加- 使的qa服务可以去调用其他服务
编写需要调用的模块的接口
代码语言:javascript复制package com.tensquare.qa.client;
import entity.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient("tensquare-base")
//@FeignClient("tensquare-base")指定调用的服务是哪个
/*
这里的tensquare-base其实是我们在写base服务module时候在yml中指定的名字
spring:
application:
name: tensquare-base
*/
public interface BaseClient {//调用base的接口
@RequestMapping(value = "label/{labelId}",method = RequestMethod.GET)
//注意这里RequestMapping里的value要写全label也要写,因为要指定到一个全路径,类似于直接在浏览器输入时候的访问地址
public Result findById(@PathVariable("labelId") String labelId);//Base中被调用的方法
//这里必须@PathVariable("labelId") 指定labelId,因为RequestMappering里的labelId是传到PathVariable中的
//这样在tensquare_base模块中才会在RequestMapper中
}
qa模块中Controller的写法(部分)
代码语言:javascript复制@RequestMapping("/problem")
public class ProblemController {
@Autowired
private BaseClient baseClient;
//注入我们在qa模块写的base服务模块调用接口
@RequestMapping(value = "label/{labelId}",method = RequestMethod.GET)
//写的和base接口中一样就行
public Result findByLabelId(@PathVariable String labelId){
Result result = baseClient.findById(labelId);
return result;
}
这样我们一个Fegin快速调用入门就结束了 我们可以用postman时候可以模拟get请求 访问: http://localhost:9003/problem/label/1 请求就会先从9003模块的problemController层通过RequestMapping找到findByLabelId会调用baseClient.findById(labelId)方法,这个时候呢,我们在BaseClient上配的@FeignClient("tensquare-base")就起了作用,他会转化请求到base微服务模块 并带着@RequestMapping中的地址和qa传过来的参数值
代码语言:javascript复制 @RequestMapping(value = "label/1",method = RequestMethod.GET)
//写的和base接口中一样就行
public Result findByLabelId(1);
SpringCloud的负载均衡
当我们采用不同端口开启多个base服务一个qa服务时候,我们利用qa去调用base时候发现请求到base集群时候实际上是每个base轮流处理请求即轮询 其实SpringCloud集成了Netfix Ribbon实现了一套客户端 负载均衡的工具。