springcloud之Netflix
Netflix体系简介
Netflix这可是个大boss,地位仅次于老大,老大各项服务依赖与它,与各种Netflix OSS组件集成,组成微服务的核心,它的小弟主要有Eureka, Hystrix, Zuul, Archaius… 太多了
核心成员
Netflix Eureka
服务中心,云端服务发现,一个基于 REST 的服务,用于定位服务,以实现云端中间层服务发现和故障转移。这个可是springcloud最牛鼻的小弟,服务中心,任何小弟需要其它小弟支持什么都需要从这里来拿,同样的你有什么独门武功的都赶紧过报道,方便以后其它小弟来调用;它的好处是你不需要直接找各种什么小弟支持,只需要到服务中心来领取,也不需要知道提供支持的其它小弟在哪里,还是几个小弟来支持的,反正拿来用就行,服务中心来保证稳定性和质量。
Netflix Ribbon
Ribbon是一个客户端负载均衡组件,帮我们实现后端服务节点动态扩容,而不影响调用方。
Netflix Hystrix
熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。比如突然某个小弟生病了,但是你还需要它的支持,然后调用之后它半天没有响应,你却不知道,一直在等等这个响应;有可能别的小弟也正在调用你的武功绝技,那么当请求多之后,就会发生严重的阻塞影响老大的整体计划。这个时候Hystrix就派上用场了,当Hystrix发现某个小弟不在状态不稳定立马马上让它下线,让其它小弟来顶上来,或者给你说不用等了这个小弟今天肯定不行,该干嘛赶紧干嘛去别在这排队了。
Netflix Zuul
Zuul 是在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架。Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门。当其它门派来找大哥办事的时候一定要先经过zuul,看下有没有带刀子什么的给拦截回去,或者是需要找那个小弟的直接给带过去。
Netflix Archaius
配置管理API,包含一系列配置管理API,提供动态类型化属性、线程安全配置操作、轮询框架、回调机制等功能。可以实现动态获取配置, 原理是每隔60s(默认,可配置)从配置源读取一次内容,这样修改了配置文件后不需要重启服务就可以使修改后的内容生效,前提使用archaius的API来读取。
Eureka和Ribbon
单机模式的Eureka和Ribbon
前置工作
1.首先是依赖的搭配使用
详细介绍参见Springcloud依赖版本搭配配置参见
2.然后再公用模块加依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<springboot.version>2.1.6.RELEASE</springboot.version>
<springcloud.version>Greenwich.SR2</springcloud.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<!-- 注意:SpringCloud最新的Greenwich版本是基于SpringBoot2.1.x(Greenwich)版本构建的
所以这里不支持SpringBoot2.2.x版本
具体SpringBoot与SpringCloud版本对应关系参见:https://spring.io/projects/spring-cloud页面最下方的Release Trains
-->
<!--<version>2.2.1.RELEASE</version>-->
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${springcloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后创建Euraka-server模块
1.创建项目启动类
@SpringBootApplication
//这是开启Eureka的注解
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) throws IOException {
SpringApplication.run(EurekaApplication.class,args);
}
}
需要注意的是,这两个注解一个是统用的,一个是专用的.
@EnableDiscoveryClient
@EnableEurekaServer
2.然后配置下yml文件
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
instance:
prefer-ip-address: true
hostname: localhost
client:
# 这个是要不要注册当前的服务注册到eureka中
register-with-eureka: false
# 是否从eureka中拉取服务表,即当前服务取注册中心拉取服务
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nmBlNO8h-1576064827399)(D:\总结\springcloud\eureks名字.png)]
3.启动项目访问Eureka日志中的地址出现管理界面
创建服务提供者
1.创建模块启动类
@SpringBootApplication
@EnableEurekaClient
public class EurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class,args);
}
}
2.配置yml文件
spring:
application:
name: eureka-provider
eureka:
# 这个是客户端的配置
client:
# 这个是是否把当前服务注册到注册中心
register-with-eureka: true
# 这个是是否要拉取服务,一般在集群中用到
fetch-registry: false
service-url:
# 这个是服务要提交服务所到的地址,同时也是eureka在浏览器的访问地址,一般是和eureka的server保持一致,
# 表明提交服务到的地址是eureka-server的地址
defaultZone: http://${eureka.instance.hostname}:8761/eureka/
# 这个是实例,即你的服务的相关配置
instance:
hostname: localhost
prefer-ip-address: true
# 这个是实例在注册中心的id
instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
server:
port: 8082
3.启动模块,查看eureka控制home实例
创建consumer模块
1.创建模块启动类
@SpringBootApplication
@EnableEurekaClient
public class EurekaConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerApplication.class,args);
}
}
2.配置yml文件
server:
port: 8081
spring:
application:
name: eureka-consumer
eureka:
client:
# 这个是要把服务注册到eureka-server的地址
service-url: http://${eureka.instance.hostname}:8761/eureka/
# 这个是是否把自己的服务注册到注册中心
register-with-eureka: true
# 这个是启动时是否拉取服务列表
fetch-registry: false
instance:
hostname: localhost
instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
# 在某些情况下,Eureka优先使用IP地址而不是主机名
# 。设置为true,当应用程序向eureka注册时,它将使用其IP地址而不是其主机名
prefer-ip-address: true
3.启动模块查看服务是否注册成功.
4.访问localhost:8081,看服务有问题否
出现的问题总结:
1.Ribbon的理解
**ribbon:**是在客户端的负载均衡,也就是说ribbon的负载均衡不在服务端,而是在客户端,这样它启动后就是先拉取服务,放在缓存中,第二次用的就是缓存中的服务列表,然后即使服务器挂了,本地还有缓存中的服务列表,短暂的也不会影响客户端的使用
这样上面的配置就有问题:fetch-registry: false:表示不拉取服务,这样就会访问localhost:8081出现500错误,错误信息是没有instances可用,所以把fetch-registry: true即可则会正常访问
Eureka集群的搭建
模块的启动类:注意启动不同的节点要改变生产环境
@SpringBootApplication
@EnableEurekaServer
public class EurekaCloudApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaCloudApplication.class,args);
}
}
主要的配置文件如下:
这样节能直接启动:
注意: 1.启动不同的节点要改变生产环境
2.注意节点启动时会报错,因为还没启动完,最后一个启动不会报错,因为他们之间会互相拉取数据.
spring:
application:
name:eureka-cloud-server
profiles:
active:
#eureka集群的搭建
eureka:
client:
# 首先这两个要打开,一个是把当前服务注册到注册中心,一个是拉取其他注册中心的服务
# 高可用
fetch-registry: true
register-with-eureka: true
instance:
prefer-ip-address: true
---
spring:
profiles: dev
eureka:
client:
service-url:
defaultZone: http://ip2:port/eureka/,http://ip3:port/eureka/
instance:
instance:
hostname: 主机的ip或主机名
---
spring:
profiles: node1
eureka:
client:
service-url:
defaultZone: http://ip1:port/eureka/,http://ip3:port/eureka/
instance:
hostname: 主机的ip或主机名
---
spring:
profiles: node2
eureka:
client:
service-url:
defaultZone: http://ip1:port/eureka/,http://ip2:port/eureka/
instance:
hostname: 主机的ip或主机名
Spring-Cloud
netflix—Feign(组件)
使用:底层封装了HttpClient
1.添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.模块启动类
@SpringBootApplication
//@EnableEurekaClient
@EnableFeignClients
public class EurekaFeignConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaFeignConsumerApplication.class,args);
}
}
3.service层的使用
@FeignClient("eureka-provider:8082")
@Service
public interface CalcService {
@GetMapping("/calc/add/{num1}/{num2}")
public ResponseInfo add(@PathVariable("num1") int num1, @PathVariable("num2") int num2);
}
4.controller层
@Controller
@RequestMapping("/calc")
@Slf4j
public class CalcController {
@Autowired
private CalcService calcService;
@RequestMapping("/add")
public String add(@RequestParam int num1, @RequestParam int num2, Model model) {
System.out.println(num1+ " " + num2);
// 以前使用SpringMVC方式,直接通过IP+端口号来调用服务
// ResponseEntity<ResponseInfo> entity = restTemplate.getForEntity("http://localhost:8081/calc/add/"+num1+"/"+num2, ResponseInfo.class);
// 引入Ribbon后,通过微服务ID访问远程服务
// ResponseEntity<ResponseInfo> entity = restTemplate.getForEntity("http://eureka-provider:8082/calc/add/"+num1+"/"+num2, ResponseInfo.class);
ResponseInfo info = calcService.add(num1, num2);
// ResponseInfo info = entity.getBody();
Map data = (Map) info.getData();
model.addAttribute("result", data.get("result"));
model.addAttribute("num1", num1);
model.addAttribute("num2", num2);
return "index";
}
}
4.yml的配置
spring:
application:
name: eureka-feign-consumer
eureka:
# 这个是客户端的配置
client:
# 这个是是否把当前服务注册到注册中心
register-with-eureka: true
# 这个是是否要拉取服务,一般在集群中用到
fetch-registry: true
service-url:
# 这个是服务要提交服务所到的地址,同时也是eureka在浏览器的访问地址,一般是和eureka的server保持一致,
# 表明提交服务到的地址是eureka-server的地址
defaultZone: http://${eureka.instance.hostname}:8761/eureka/
# 这个是实例,即你的服务的相关配置
instance:
hostname: localhost
prefer-ip-address: true
# 这个是实例在注册中心的id
instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
server:
port: 8088
feign:
client:
config:
# calc-service-provider: 这一级可以写具体的微服务名称或者default,default代表全局配置,影响所有微服务的调用
default:
connectTimeout: 1000
readTimeout: 2000
5.提供者和Eureka服务的创建
Spring-Cloud—hystrix(组件)
两种方式分别是:hystrix和riboon的整合使用;hystrix和feign整合使用
Hystrix(熔断器)和Ribbon的整合使用
Hystrix和ribbon的使用主要是hystrix和ReatTemplate的使用.
什么是hystrix?
在分布式环境中,许多服务依赖项中的一些不可避免地会失败。
Hystrix是一个库,可通过添加延迟容错和容错逻辑来帮助您控制这些分布式服务之间的交互。
Hystrix通过隔离服务之间的访问点,阻止它们之间的级联故障以及提供后备选项来实现这一目标,这些都可以提高系统的整体恢复能力
通俗的说Hystrix是Netflix公司开源的一个用于服务调用的断路器组件,给我们提供了包括服务熔断、降级、超时、资源隔离在内的完整解决方案。
具体使用
1.导入用到的依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2.启动类开启Hystrix熔断
@SpringBootApplication
@EnableCircuitBreaker //开启熔断
@EnableEurekaClient
public class HystrixRestTemplateApplication {
@LoadBalanced //tibbon的使用,主要用来请求远程服务和负载均衡使用
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(HystrixRestTemplateApplication.class,args);
}
}
3.web控制层的使用
/**
* 计算器
*/
@Controller
@RequestMapping("/calc")
@Slf4j
public class CalcController {
@Autowired
private RestTemplate restTemplate;
/**
* 下面是熔断的使用
* @param num1
* @param num2
* @param model
* @return
*/
@HystrixCommand(
/**
* 这是熔断点的定义
*/
fallbackMethod = "addFallback",
/**
* commandKey用于在Properties文件中配置此Command的参数,也可以直接用注解在这里配置参数
*/
commandKey = "calc_add_command"
)
@RequestMapping("/add")
public String add(@RequestParam int num1, @RequestParam int num2, Model model) {
System.out.println(num1+ " " + num2);
// 以前使用SpringMVC方式,直接通过IP+端口号来调用服务
// ResponseEntity<ResponseInfo> entity = restTemplate.getForEntity("http://localhost:8081/calc/add/"+num1+"/"+num2, ResponseInfo.class);
// 引入Ribbon后,通过微服务ID访问远程服务
ResponseEntity<ResponseInfo> entity = restTemplate.getForEntity("http://eureka-provider:8082/calc/add/"+num1+"/"+num2, ResponseInfo.class);
ResponseInfo info = entity.getBody();
Map data = (Map) info.getData();
model.addAttribute("result", data.get("result"));
model.addAttribute("num1", num1);
model.addAttribute("num2", num2);
return "index";
}
/**
* 熔断方法,当服务发生熔断是调用此方法
* @param num1
* @param num2
* @param model
* @return
*/
public String addFallback(@RequestParam int num1, @RequestParam int num2, Model model){
model.addAttribute("num1", num1);
model.addAttribute("num2", num2);
model.addAttribute("result", "-1");
return "index";
}
}
注意:这里的 @HystrixCommand中的参数commandkey的使用是,用于在Properties文件中配置此Command的参数,也可以直接用注解在这里配置参数.
4.最重要的yml中的配置
spring:
application:
name: eureka-consumer-rest_template-hystrix
eureka:
# 这个是客户端的配置
client:
# 这个是是否把当前服务注册到注册中心
register-with-eureka: true
# 这个是是否要拉取服务,一般在集群中用到
fetch-registry: true
service-url:
# 这个是服务要提交服务所到的地址,同时也是eureka在浏览器的访问地址,一般是和eureka的server保持一致,
# 表明提交服务到的地址是eureka-server的地址
defaultZone: http://${eureka.instance.hostname}:8761/eureka/
# 这个是实例,即你的服务的相关配置
instance:
hostname: localhost
prefer-ip-address: true
# 这个是实例在注册中心的id
instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
# hystrix中的核心配置
hystrix:
command:
calc_add_command:
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 #设置熔断器判定超时的时间,超过此时间的请求会执行降级逻辑,默认1s
circuitBreaker:
requestVolumeThreshold: 2 #设置熔断阈值,在熔断统计窗口期内,错误请求(超时、异常)次数达到阈值就会触发熔断,执行降级逻辑,默认20
sleepWindowInMilliseconds: 10000 #设置熔断器多久进入半开状态,然后再次尝试确定熔断器是否应再次关闭,默认5s
errorThresholdPercentage: 50 #设置在熔断统计窗口期内,错误请求达到百分之多少触发熔断,默认50
metrics:
rollingStats:
timeInMilliseconds: 5000 #熔断度量窗口期时间, 默认10s
server:
port: 8099
5.启动项目测试
Hystrix和Feign的整合使用
1.导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>
2.web控制层
@Controller
@RequestMapping("/calc")
@Slf4j
public class CalcController {
@Autowired
private CalcService calcService;
@RequestMapping("/add")
public String add(@RequestParam int num1, @RequestParam int num2, Model model) {
System.out.println(num1+ " " + num2);
// 以前使用SpringMVC方式,直接通过IP+端口号来调用服务
// ResponseEntity<ResponseInfo> entity = restTemplate.getForEntity("http://localhost:8081/calc/add/"+num1+"/"+num2, ResponseInfo.class);
// 引入Ribbon后,通过微服务ID访问远程服务
// ResponseEntity<ResponseInfo> entity = restTemplate.getForEntity("http://eureka-provider:8082/calc/add/"+num1+"/"+num2, ResponseInfo.class);
ResponseInfo info = calcService.add(num1, num2);
// ResponseInfo info = entity.getBody();
Map data = (Map) info.getData();
model.addAttribute("result", data.get("result"));
model.addAttribute("num1", num1);
model.addAttribute("num2", num2);
return "index";
}
}
3.service层
@FeignClient(value = "eureka-provider:8082",fallback = FallbackClient.class)
@Service
public interface CalcService {
@GetMapping("/calc/add/{num1}/{num2}")
public ResponseInfo add(@PathVariable("num1") int num1,@PathVariable("num2") int num2);
}
需要注意的是fallback熔断方法的实现要和实现的接口的请求地址分开,因为实现接口会默认继承GetMappig 的请求地址,防止出现暧昧关系
熔断方法
@Component
@RequestMapping("/fallback")
public class FallbackClient implements CalcService {
@Override
public ResponseInfo add(int num1, int num2) {
Map data = new HashMap();
data.put("num1", num1);
data.put("num2", num2);
data.put("result", -1);
ResponseInfo responseInfo = new ResponseInfo(203, "降级结果", data);
return responseInfo;
}
}
4.配置文件
spring:
application:
name: eureka-consumer-feign-hystrix
eureka:
# 这个是客户端的配置
client:
# 这个是是否把当前服务注册到注册中心
register-with-eureka: true
# 这个是是否要拉取服务,一般在集群中用到
fetch-registry: true
service-url:
# 这个是服务要提交服务所到的地址,同时也是eureka在浏览器的访问地址,一般是和eureka的server保持一致,
# 表明提交服务到的地址是eureka-server的地址
defaultZone: http://${eureka.instance.hostname}:8761/eureka/
# 这个是实例,即你的服务的相关配置
instance:
hostname: localhost
prefer-ip-address: true
# 这个是实例在注册中心的id
instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
hystrix:
command:
# default: # 设置全局熔断参数
CalcService#add(int,int): #设置某个feign client的熔断参数
execution:
isolation:
thread:
timeoutInMilliseconds: 2000 #设置熔断器判定超时的时间,超过此时间的请求会执行降级逻辑,默认1s
circuitBreaker:
requestVolumeThreshold: 2 #设置熔断阈值,在熔断统计窗口期内,错误请求(超时、异常)次数达到阈值就会触发熔断,执行降级逻辑,默认20
sleepWindowInMilliseconds: 10000 #设置熔断器多久进入半开状态,然后再次尝试确定熔断器是否应再次关闭,默认5s
errorThresholdPercentage: 50 #设置在熔断统计窗口期内,错误请求达到百分之多少触发熔断,默认50
metrics:
rollingStats:
timeInMilliseconds: 5000 #熔断度量窗口期时间, 默认10s
feign:
client:
config:
# calc-service-provider: 这一级可以写具体的微服务名称或者default,default代表全局配置,影响所有微服务的调用
default:
connectTimeout: 1000
readTimeout: 2000
hystrix:
enabled: true
server:
port: 8100
5.需要注意的问题
在feign中默认的hystrix是默认关闭的,如果不打开的话,会出现找不到fallback的错误,错误类型是500.
监控工具
SpringBoot Actuator
SpringBoot Actuactor是SpringBoot提供的一个监控工具,通过他我们可以看到应用运行工程中的很多有用的信息:
ID | Description | Enabled by default |
---|---|---|
auditevents | Exposes audit events information for the current application. | Yes |
beans | Displays a complete list of all the Spring beans in your application. | Yes |
conditions | Shows the conditions that were evaluated on configuration and auto-configuration classes and the reasons why they did or did not match. | Yes |
configprops | Displays a collated list of all @ConfigurationProperties . | Yes |
env | Exposes properties from Spring’s ConfigurableEnvironment . | Yes |
flyway | Shows any Flyway database migrations that have been applied. | Yes |
health | Shows application health information. | Yes |
httptrace | Displays HTTP trace information (by default, the last 100 HTTP request-response exchanges). | Yes |
info | Displays arbitrary application info. | Yes |
loggers | Shows and modifies the configuration of loggers in the application. | Yes |
liquibase | Shows any Liquibase database migrations that have been applied. | Yes |
metrics | Shows ‘metrics’ information for the current application. | Yes |
mappings | Displays a collated list of all @RequestMapping paths . | Yes |
scheduledtasks | Displays the scheduled tasks in your application. | Yes |
sessions | Allows retrieval and deletion of user sessions from a Spring Session-backed session store. Not available when using Spring Session’s support for reactive web applications. | Yes |
shutdown | Lets the application be gracefully shutdown. | No |
threaddump | Performs a thread dump. | Yes |
如果应用是一个Web应用(指引入了SpringMVC、Spring WebFlux或者Jersey),就可以用下面这些监控端点
ID | Description | Enabled by default |
---|---|---|
heapdump | Returns an hprof heap dump file. | Yes |
jolokia | Exposes JMX beans over HTTP (when Jolokia is on the classpath, not available for WebFlux). | Yes |
logfile | Returns the contents of the logfile (if logging.file or logging.path properties have been set). Supports the use of the HTTP Range header to retrieve part of the log file’s content. | Yes |
prometheus | Exposes metrics in a format that can be scraped by a Prometheus server. | Yes |
除了上面列出来的,其他第三方模块还会提供一些特有的监控端点,如zuul提供的/routes
Springcloud-zuul(路由网关)
Zuul介绍
Zuul是Netflx开源的微服务网关。可以和Eureka、Ribbon、Hystrix配合使用,一个主要的功能就是可以将后端众多的微服务屏蔽、整合,对前端提供一套统一的服务(有点像是后端的Facade)。
Zuul提供了以下几项支持:
- 认证安全: 识别每一个资源的验证要求,并拒绝那些不符的请求
- 监控
- 动态路由: 动态将请求路由到不同后端集群
- 压力测试: 逐渐增加指向集群的流量,以了解性能
- 金丝雀测试: 灰度发布
- 流量控制: 为每一种负载类型分配对应容量,并弃用超出限定值的请求
- 服务迁移
- 静态资源响应处理: 边缘位置进行响应,避免转发到内部集群
zuul用的地方是
一般用在服务的提供者
1.加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.创建springcloud-zuul
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
3.配置
server:
port: 10003
spring:
application:
name: zuul-server
eureka:
# 这个是客户端的配置
client:
# 这个是是否把当前服务注册到注册中心
register-with-eureka: true
# 这个是是否要拉取服务,一般在集群中用到
fetch-registry: true
service-url:
# 这个是服务要提交服务所到的地址,同时也是eureka在浏览器的访问地址,一般是和eureka的server保持一致,
# 表明提交服务到的地址是eureka-server的地址
defaultZone: http://${eureka.instance.hostname}:8761/eureka/
# 这个是实例,即你的服务的相关配置
instance:
hostname: localhost
prefer-ip-address: true
# 这个是实例在注册中心的id
instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
management:
endpoints:
web:
exposure:
include: "*"
zuul:
routes:
# 这种方式配置路由规则:前面的key是微服务名称,后面是匹配路径
# calc-service-provider: /calcApi/**
# 这种方式配置路由规则:第一级的key可以随便取(路由名称),下面可以配置更多key、value(相比上面一种配置更强大)
calc-proxy:
serviceId: eureka-provider # 有效的微服务名称
path: /calc/** # 访问路径
strip-prefix: false # 是否在网关层面消耗掉指定服务的路由规则前缀
# taotao-rest-proxy:
# serviceId: taotao-rest
# path: /rest/**
注意上上面的strip-prefix: 值的用法
1.上面的strip-prefix: false设置false代表你访问**localhost:10003/calc/****会跳转到对应的服务是eureka-provider,然后到注册中心找到对应的服务,localhost:8082/calc/add/55/66
2. 上面的strip-prefix: false设置false代表你访问localhost:**10003/calc/calc/****会跳转到对应的服务是eureka-provider,然后到注册中心找到对应的服务,localhost:8082/calc/add/55/66
代理传统的服务
配置如下
server:
port: 9100
spring:
application:
name: zuul-server
eureka:
client:
service-url:
defaultZone: http://${eureka.instance.hostname}:${eureka.client.eureka-server-port}/eureka/
eureka-server-port: 8761
instance:
prefer-ip-address: true #在某些情况下,Eureka优先使用IP地址而不是主机名。设置为true,当应用程序向eureka注册时,它将使用其IP地址而不是其主机名
instance-id: ${spring.application.name}:${spring.application.instance_id:${server.port}}
hostname: node1.john.com
management:
endpoints:
web:
exposure:
include: "*"
zuul:
routes:
# 这种方式配置路由规则:前面的key是微服务名称,后面是匹配路径
# calc-service-provider: /calcApi/**
# 这种方式配置路由规则:第一级的key可以随便取(路由名称),下面可以配置更多key、value(相比上面一种配置更强大)
calc-proxy:
serviceId: calc-service-provider # 有效的微服务名称
path: /calc/** # 访问路径
strip-prefix: false # 是否在网关层面消耗掉指定服务的路由规则前缀
#代理传统的服务:
# taotao-rest-proxy:
# serviceId: taotao-rest
# path: /rest/**
taotao-rest-proxy-forward: # 使用forward本地转发(就是将匹配到路由规则的请求,转发到网关本地应用中去处理)
path: /rest-f/**
url: forward:/rest
# 比如浏览器访问:http://localhost:9100/api/rest-f/content/getall/89
# 会被转发到:http://localhost:9100/rest/content/getall/89
ignored-services: "*" # 忽略所有未显示配置路由规则的微服务
prefix: /api
strip-prefix: true # 是否在网关层面消耗掉全局前缀
# 使用Zuul代理未接入Eureka的传统服务
taotao-rest:
ribbon:
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList #如果不配置ServerList类型为ConfigurationBasedServerList的话就需要禁用ribbon的eureka支持
ConnectTimeout: 500
ReadTimeout: 2000
listOfServers: http://localhost:8081
calc-service-provider:
ribbon:
ReadTimeout: 2000
ConnectTimeout: 500