SpringCloud的学习记录
Posted xumblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud的学习记录相关的知识,希望对你有一定的参考价值。
这一章节讲zuul的使用.
在我们生成的Demo项目上右键点击New->Module->spring Initializr, 然后next, 填写Group和Artifact等信息,
这里Artifact填写eurekazuul, 再次next, 选择内容如下的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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.xum</groupId> <artifactId>eureka-zuul</artifactId> <version>0.0.1-SNAPSHOT</version> <name>eureka-zuul</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version> </properties> <dependencies> <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.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </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> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project>
eureka-zuul模型结构如下:
1. 首先是EurekaZuulApplication.java内容如下:
package com.xum.eurekazuul; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard; import org.springframework.cloud.netflix.turbine.EnableTurbine; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy // 这里是启用zuul路由的注解 @EnableHystrixDashboard @EnableTurbine public class EurekaZuulApplication { public static void main(String[] args) { SpringApplication.run(EurekaZuulApplication.class, args); } }
2. application.yml内容如下:
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8773 zuul: // 这里定义了两个api接口的路由, 一个指向ribbon-consumer, 一个指向fegin-client routes: api-a: path: /api-a/** serviceId: ribbon-consumer api-b: path: /api-b/** serviceId: fegin-client turbine: aggregator: cluster-config: default app-config: ‘*‘ cluster-name-expression: new String("default") spring: application: name: eureka-zuul management: endpoint: health: show-details: always endpoints: web: exposure: include: ‘*‘
3. 然后是PermissionsFilter.java内容如下:
package com.xum.eurekazuul.filter; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.exception.ZuulException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE; @Component public class PermissionsFilter extends ZuulFilter { private static final Logger LOG = LoggerFactory.getLogger(PermissionsFilter.class); @Override public String filterType() { return PRE_TYPE; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; /*RequestContext ctx = RequestContext.getCurrentContext(); return (boolean) ctx.get("isSuccess");*/ } @Override public Object run() throws ZuulException { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); LOG.info(String.format("%s AccessNameFilter request to %s", request.getMethod(), request.getRequestURL().toString())); String name = request.getParameter("name");// 获取请求的参数 if(null != name && "xum".equalsIgnoreCase(name)) { // 在向eureka-client项目里调用api的时候,检查带的name内容是否是xum ctx.setSendZuulResponse(true); ctx.setResponseStatusCode(200); ctx.set("isSuccess", true); return null; }else{ ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); ctx.setResponseBody("{\\"result\\":\\"name is not correct!\\"}"); ctx.set("isSuccess", false); return null; } } }
4. 其次就是ApiFallbackProvider.java内容如下:
package com.xum.eurekazuul.provider; import com.netflix.hystrix.exception.HystrixTimeoutException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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; @Component public class ApiFallbackProvider implements FallbackProvider { private static final Logger LOG = LoggerFactory.getLogger(ApiFallbackProvider.class); @Override public String getRoute() { LOG.info("ApiFallbackProvider=>getRoute"); return "*"; } @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { LOG.info(String.format("route:%s,exceptionType:%s,stackTrace:%s", route, cause.getClass().getName(), cause.getStackTrace())); String message = ""; if (cause instanceof HystrixTimeoutException) { message = "Timeout"; } else { message = "Service exception"; } return fallbackResponse(message); } public ClientHttpResponse fallbackResponse(String message) { return new ClientHttpResponse() { @Override public HttpStatus getStatusCode() throws IOException { LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getStatusCode"); return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getRawStatusCode"); return 200; } @Override public String getStatusText() throws IOException { LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getStatusText"); return "OK"; } @Override public void close() { LOG.info("ApiFallbackProvider=>ClientHttpResponse=>close"); } @Override public InputStream getBody() throws IOException { LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getBody"); String bodyText = String.format("{\\"code\\": 999,\\"message\\": \\"Service unavailable:%s\\"}", message); return new ByteArrayInputStream(bodyText.getBytes()); } @Override public HttpHeaders getHeaders() { LOG.info("ApiFallbackProvider=>ClientHttpResponse=>getHeaders"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }; } }
顺序启动一下项目:
1. eureka-server
2. config-server
3. eureka-client
4. fegin-client
5. ribbon-consumer
6. zuul-client
然后再浏览器或则post man中输入http://localhost:8773/api-a/ribbonconsumer/test?name=xum, 显示内容如下:
在eureka-zuul项目里Event log打印出如下类似的log:
2019-03-31 14:52:51.881 INFO 1976 --- [nio-8773-exec-9] c.x.eurekazuul.filter.PermissionsFilter : POST AccessNameFilter request to http://localhost:8773/api-a/ribbonconsumer/test
当输入http://localhost:8773/api-a/ribbonconsumer/test, 不带任何参数的时候, 显示内容如下, 路由网关提示name不正确.
然后再post man中输入http://localhost:8773/api-b/feign/feignconsumer?name=xum, 内容如下:
也能在eureka-client项目的Event log里看到如下类似的log:
2019-03-31 14:58:27.395 INFO 1976 --- [nio-8773-exec-5] c.x.eurekazuul.filter.PermissionsFilter : POST AccessNameFilter request to http://localhost:8773/api-b/feign/feignconsumer
相同的道理, 如果参数没有name或则name只不对, 路由网关都会提示出错.
当eureka-client项目没有启动的时候, Hyrtrix会进行相应自我保护.
以上是关于SpringCloud的学习记录的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud——Eureka Feign Ribbon Hystrix Zuul等关键组件的学习与记录
SpringCloud系列十一:SpringCloudStream(SpringCloudStream 简介创建消息生产者创建消息消费者自定义消息通道分组与持久化设置 RoutingKey)(代码片段
ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)(代码片段