五、Spring Cloud - Netflix(Zuul服务网关构建代码层面)

xiaoxiao2021-02-28  73

五、Spring Cloud - Netflix(Zuul服务网关构建代码层面)

本文依然是基于http://blog.didispace.com/springcloud5/博主提供的部分代码,以及大部分的使用思路。

1)项目的结构(5个都要用到,不单单2017-Netflix_Zuul哦)

2)看代码

pom.xml

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sample</groupId> <artifactId>2017-Netflix_Zuul</artifactId> <version>1.0.1-SNAPSHOT</version> <packaging>war</packaging> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <!-- 指定source和target的版本 --> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency> <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId>hystrix-javanica</artifactId> </dependency> --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zuul</artifactId> </dependency> </dependencies> </project>application.properties spring.application.name=api-gateway server.port=5555 # 启动2017-Netflix_ServiceA和2017-Netflix_ServiceB, 它们两提供不同的两个服务 # routes to url (第一种 url映射方式) zuul.routes.api-a-url.path=/api-a-url/** zuul.routes.api-a-url.url=http://localhost:8091/ # routes to serviceId (第二种 serviceId映射方式) zuul.routes.api-a.path=/api-a/** zuul.routes.api-a.serviceId=netflix-service-a zuul.routes.api-b.path=/api-b/** zuul.routes.api-b.serviceId=netflix-service-b # 用于验证zuul自带的负载均衡功能, 启动2017-Netflix_Service1和2017-Netflix_Service2, 它们两提供同一个服务netflix-service zuul.routes.api-service.path=/api-service/** zuul.routes.api-service.serviceId=netflix-service eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/ # Zuul测试连接如下 #http://localhost:5555/api-a-url/add?a=1&b=2 #http://localhost:5555/api-a/add?a=1&b=2 #http://localhost:5555/api-service/add?a=1&b=2 # 下面其实还是走原有Ribbon, 已经测试过了 #http://localhost:5555/zuulRibbonCallAddService zuul.routes.customers=/customers/** package com.jack.ssm.fallback; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; /** * ClassName:GenericZuulFallbackProvider.java * * http://tachniki.blogspot.in/2017/02/generic-ZuulFallbackProvider.html参考这篇文章 * 将多个熔断器抽象成一个公共的熔断类,然后在spring boot application里面根据不同的route ID,实现对应的熔断器. * * Date: 2017年6月7日下午1:49:35 * @author Jack.Huang * @version V1.0 * @since JDK 1.7.0_60/JDK 1.8.0_45 */ public class GenericZuulFallbackProvider implements ZuulFallbackProvider { private String responseBody = "{\"message\":\"Service Unavailable. Please try after sometime\"}"; private HttpHeaders headers = null; private String route = null; private int rawStatusCode = 503; private HttpStatus statusCode = HttpStatus.SERVICE_UNAVAILABLE; private String statusText = "Service Unavailable"; @Override public String getRoute() { if (route == null) route = "route"; // 若为空, 则熔断默认route ID="route", 但我配置文件没配这个这只是一种实现的样例. return route; } /** * 熔断器会调用下面的fallbackResponse方法,最终模拟返回一个ClientHttpResponse. * 里面包含HttpHeaders、rawStatusCode、statusCode和responseBody等信息,这些信息都可以自定义返回值. * MediaType则包含多种返回信息的格式Json、Pdf、Image等等. * * @see org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider#fallbackResponse() */ @Override public ClientHttpResponse fallbackResponse() { return new ClientHttpResponse(){ @Override public InputStream getBody() throws IOException { if (responseBody == null) responseBody ="{\"message\":\"Service Unavailable. Please try after sometime\"}"; return new ByteArrayInputStream(responseBody.getBytes()); } @Override public HttpHeaders getHeaders() { if (headers == null) { headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); } return headers; } @Override public void close() { } @Override public int getRawStatusCode() throws IOException { return rawStatusCode; } @Override public HttpStatus getStatusCode() throws IOException { if (statusCode == null) statusCode = HttpStatus.SERVICE_UNAVAILABLE; return statusCode; } @Override public String getStatusText() throws IOException { if (statusText == null) statusText = "Service Unavailable"; return statusText; } }; } public String getResponseBody() { return responseBody; } public void setResponseBody(String responseBody) { this.responseBody = responseBody; } public HttpHeaders getHeaders() { return headers; } public void setHeaders(HttpHeaders headers) { this.headers = headers; } public int getRawStatusCode() { return rawStatusCode; } public void setRawStatusCode(int rawStatusCode) { this.rawStatusCode = rawStatusCode; } public HttpStatus getStatusCode() { return statusCode; } public void setStatusCode(HttpStatus statusCode) { this.statusCode = statusCode; } public String getStatusText() { return statusText; } public void setStatusText(String statusText) { this.statusText = statusText; } public void setRoute(String route) { this.route = route; } } package com.jack.ssm; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import org.springframework.boot.SpringApplication; import org.springframework.cloud.client.SpringCloudApplication; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpResponse; import org.springframework.web.client.RestTemplate; import com.jack.ssm.fallback.GenericZuulFallbackProvider; /** * ClassName:RibbonApplication.java * Date: 2017年6月5日下午5:06:00 * @author Jack.Huang * @version V1.0 * @since JDK 1.7.0_60/JDK 1.8.0_45 */ @EnableZuulProxy //@EnableZuulServer @SpringCloudApplication // 它整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker public class ZuulRibbonApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ZuulRibbonApplication.class, args); } @Bean public ZuulFallbackProvider routeAPIAZuulFallbackProvider() { GenericZuulFallbackProvider routeZuulFallback = new GenericZuulFallbackProvider(); routeZuulFallback.setRoute("netflix-service-a"); return routeZuulFallback; } @Bean public ZuulFallbackProvider routeAPIbZuulFallbackProvider() { GenericZuulFallbackProvider routeZuulFallback = new GenericZuulFallbackProvider(); routeZuulFallback.setRoute("netflix-service-b"); return routeZuulFallback; } @Bean public ZuulFallbackProvider netflixServiceZuulFallbackProvider() { GenericZuulFallbackProvider portalZullFallback = new GenericZuulFallbackProvider(); portalZullFallback.setRoute("netflix-service"); portalZullFallback.setRawStatusCode(200); portalZullFallback.setStatusCode(HttpStatus.OK); portalZullFallback.setResponseBody("We are little busy. Comeback After Sometime"); return portalZullFallback; } /* @Bean public ZuulFallbackProvider zuulFallbackProvider() { return new ZuulFallbackProvider() { @Override public String getRoute() { return "customers"; } @Override public ClientHttpResponse fallbackResponse() { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { return 200; } @Override public String getStatusText() throws IOException { return "OK"; } @Override public void close() { } @Override public InputStream getBody() throws IOException { return new ByteArrayInputStream("fallback".getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }; } }; } */ } 3) 验证Zuul路由跳转功能

启动2017-Netflix_Server

java -jar 2017_Netflix_Eureka_Server-1.0.1-SNAPSHOT.jar --spring.profiles.active=eureka

再分别启动2017-Netflix_ServiceA、2017-Netflix_ServiceB以及2017-Netflix_Zuul

他们的启动命令都是这个, spring boot嘛: G:\GIT-WORKPLACE\project\2017-Netflix_Zuul>mvn spring-boot:run

Zuul测试连接如下: http://localhost:5555/api-a-url/add?a=1&b=2&accessToken=token http://localhost:5555/api-a/add?a=1&b=2&accessToken=token http://localhost:5555/api-b-url/add?a=1&b=2&accessToken=token http://localhost:5555/api-b/add?a=1&b=2&accessToken=token

4) 验证Zuul负载均衡功能

启动2017-Netflix_Server

java -jar 2017_Netflix_Eureka_Server-1.0.1-SNAPSHOT.jar --spring.profiles.active=eureka

再分别启动2017-Netflix_Service1、2017-Netflix_Service1以及2017-Netflix_Zuul

Zuul测试连接如下:

http://localhost:5555/api-service/add?a=1&b=2&accessToken=token

Zuul负载均衡功能默认是实现的,代码不需要写任何东西。

5) 验证Zuul熔断功能

Zuul熔断功能默认也是实现的,但是需要写东西哦。

官网有例子http://cloud.spring.io/spring-cloud-static/Dalston.RELEASE/#hystrix-fallbacks-for-routes,

但是很tm坑啊,按官网的是没效果的,还需要在ZuulRibbonApplication加入如下类似代码。

@Bean public ZuulFallbackProvider routeAPIAZuulFallbackProvider() { GenericZuulFallbackProvider routeZuulFallback = new GenericZuulFallbackProvider(); routeZuulFallback.setRoute("netflix-service-a"); return routeZuulFallback; }参考歪国友人的文章: http://tachniki.blogspot.in/2017/02/generic-ZuulFallbackProvider.html

歪果友人同时也提供了一个公共熔断的实现方案,以及不同服务路由的不同熔断规则的实现方案。

附带源码

https://Git.coding.NET/JackHuang0801/project.git

拉分支release-spring-cloud-1.1

转载请注明原文地址: https://www.6miu.com/read-45446.html

最新回复(0)