一:创建 eureka-zuul-client 服务
1.1 在主Maven工程中创建一个新的 Module 工程,命名为eureka-zuul-client。采用Spring Initializr 的方式的方式创建。
1.2 eureka-zuul-client 的 pom.xml 的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.springcloud</groupId>
<artifactId>springcloud-hx</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>eureka-zuul-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka-zuul-client</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<version>0.0.20131108.vaadin1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1.3 主Module 的 的 pom.xml 加上:
1.4 eureka-zuul-client 的 配置文件 application.yml 的内容如下:
server:
port: 8768
spring:
#配置程序名为eureka-zuul-client
application:
name: eureka-zuul-client
eureka:
client:
#服务注册地址
serviceUrl:
#注意: Eureka Server 的注册地址
#将服务提供者注册到三个Eureka Server中去
#defaultZone: http://peer1:8001/eureka/,http://peer2:8002/eureka/,http://peer3:8003/eureka/
#defaultZone: http://peer1:8001/eureka/
defaultZone: http://localhost:8761/eureka/
#spring-cloud-starter-zuul依赖时,它自身就包含了对 spring-cloud-starter-hystrix 和 spring-cloud-starter-ribbon模块的依赖,
#所以 Zuul天生就拥有线程隔离和断路器的自我保护功能,以及 对服务调用的客户端负载均衡功能。
zuul:
routes:
#这两个配置可以将以 "/hiApi" 开头的Url 路由到 eureka-client服务。zuul.routes.hiApi 中的"hiApi"是自己定义的
#如果某服务存在多个实例,Zuul结合ribbon 会做负载均衡
hiApi:
path: /hiApi/**
serviceId: eureka-client
ribbonApi:
path: /ribbonApi/**
sereviceId: eureka-ribbon-client
feignApi:
path: /feignApi/**
serviceId: eureka-feign-client
feignHystrixApi:
path: /feignHystrixApi/**
serviceId: eureka-feign-hystrix-client
#给每一个服务的API接口加前缀
prefix: /v1
ribbon:
ReadTimeout: 60000
ConnectTimeout: 60000
1.5 在启动类上加上 @EnableDiscoveryClient 开启服务注册于发现,加上@EnableZuulProxy //开启Zuul 的功能,代码如下:
package com.example.eurekazuulclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
//开启服务注册于发现
@EnableDiscoveryClient
//开启Zuul 的功能
@EnableZuulProxy
public class EurekaZuulClientApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaZuulClientApplication.class, args);
}
}
1.6 启动 eureka-serve, eureka-client (8762,8763 端口),eureka-zuul-client ,eureka-feign-hystrix-client 服务,浏览器访问 http://localhost:8761/
多次访问http://localhost:8768/v1/hiApi/HiController/hi/java,得到如下结果:
可以看出,实现了负载均衡。
访问http://localhost:8768/v1/feignHystrixApi/FeignHystrixController/hi/java
1.7 在 Zuul 上配置熔断器
默认情况下,经过Zuul的请求都会使用Hystrix进行包裹,所以Zuul本身就具有熔断器的功能。
所以当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,我们可以进行熔断处理。
如何实现:实现 FallbackProvider 接口,实现该接口的getRoute() 和 fallbackResponse() 方法。
新建一个MyFallbackHystrix类,代码如下:
package com.example.eurekazuulclient.hystrix;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.cloud.netflix.zuul.filters.route.FallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
*默认情况下,经过Zuul的请求都会使用Hystrix进行包裹,所以Zuul本身就具有熔断器的功能。
*所以当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,我们可以进行熔断处理。
*如何实现:实现 FallbackProvider 接口,实现该接口的getRoute() 和 fallbackResponse() 方法
*/
@Component
public class MyFallbackHystrix implements FallbackProvider {
/**
* 返回值表示需要针对此微服务做熔断功能
* (该名称一定要是注册进入 eureka 微服务中的那个 serviceId 名称);
*
* @return
*/
@Override
public String getRoute() {
//api服务id,如果需要所有调用都支持回退,则return "*"或return null
return "*";
}
@Override
public ClientHttpResponse fallbackResponse(String route, Throwable cause) {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return HttpStatus.OK.value();
}
@Override
public String getStatusText() throws IOException {
return HttpStatus.OK.getReasonPhrase();
}
@Override
public void close() {
}
/**
* 当 springms-provider-user 微服务出现宕机后,客户端再请求时候就会返回 fallback 等字样的字符串提示;
* 但对于复杂一点的微服务,我们这里就得好好琢磨该怎么友好提示给用户了;
* 如果请求用户服务失败,返回什么信息给消费者客户端
* @return
* @throws IOException
*/
@Override
public InputStream getBody() throws IOException {
/*JSONObject r = new JSONObject();
try {
r.put("state", "9999");
r.put("msg", "系统错误,请求失败");
} catch (JSONException e) {
e.printStackTrace();
}
return new ByteArrayInputStream(r.toString().getBytes("UTF-8"));*/
return new ByteArrayInputStream((getRoute() + " 出错了").getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
//和body中的内容编码一致,否则容易乱码
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
return headers;
}
};
}
}
浏览器访问:http://localhost:8768/v1/feignHystrixApi/FeignHystrixController/hi/java
关闭 eureka-client 服务,再次访问,
这时,我们会发现,没有返回fallbackResponse类中的回调信息,而是返回了 eureka-feign-hystrix-client 项目 中 熔断器的回调信息。
接着,我们重新开启 eureka-client 服务,这次关闭 eureka-feign-hystrix-client 这个服务,再次访问:
这时候, eureka-zuul-client中 fallbackResponse 的返回生效了。
所以可以发现,eureka-feign-hystrix-client 熔断器的回调执行 > eureka-zuul-client 熔断器的回调执行。
来源:CSDN
作者:刘德华一不小心就打代码
链接:https://blog.csdn.net/weixin_40991408/article/details/103959378