此文章是看了方志朋老师的教材自己写的框架demo:
学习spring cloud推荐大家看下方志朋老师的史上最简单的 SpringCloud 教程 | 终章,地址如下:
https://blog.csdn.net/forezp/article/details/70148833
1.简介与作用
在微服务架构中,需要几个基础的服务治理组件,包括服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,由这几个基础组件相互协作,共同组建了一个简单的微服务系统。一个简答的微服务系统如下图:
在spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul集群),然后再到具体的服务,服务统一注册到高可用的服务注册中心集群,服务的所有的配置文件由配置服务管理,配置服务的配置文件放在Git或svn仓库,方便开发人员随时改配置
Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。
2.代码实现(路由)
2.1 创建maven项目
2.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.0modelVersion> <groupId>com.immogroupId> <artifactId>immo-zuulartifactId> <version>0.0.1-SNAPSHOTversion> <parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-parentartifactId> <version>1.5.2.RELEASEversion> <relativePath/> parent> <properties> <project.build.sourceEncoding>UTF-8project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding> <java.version>1.7java.version> properties> <dependencies> <dependency> <groupId>org.springframework.cloudgroupId> <artifactId>spring-cloud-starter-eurekaartifactId> <version>1.3.4.RELEASEversion> dependency> <dependency> org.springframework.cloud spring-cloud-starter-zuul 1.3.4.RELEASE dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> dependencies> project> |
2.3 添加启动类
在src/main/java 下新建包 com.immo 创建 ZuulApplication.java
在src/main/resources 下新建 application.properties
编写ZuulApplication.java
@EnableZuulProxy,开启zuul的功能
package com.immo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class,args); } } |
编写application.properties
#发布到的eureka地址 eureka.client.serviceUrl.defaultZOne=http://localhost:9000/eureka/ #端口 server.port=8080 #此项目的服务名称 spring.application.name=immo-zuul #路由配置 zuul.routes.api-a.path= /api-a/** zuul.routes.api-a.serviceId: immo-feign #路由配置 zuul.routes.api-b.path: /api-b/** zuul.routes.api-b.serviceId: immo-client |
注:如果没有设置路由配置也可以通过 localhost:8080/服务名/** 来访问
2.4测试(路由)
先后启动immo-eureka,immo-client,immo-feign,immo-zuul这四个项目:
访问 http://localhost:8080/api-a/getServerName
访问 http://localhost:8080/api-b/getServerName
证明路由起作用了
注:如果没有设置路由配置也可以通过 localhost:8080/服务名/** 来访问
3.代码实现(过滤)
zuul不仅只是路由,并且还能过滤,做一些安全验证。继续改造工程创建包com.immo.filter,在包下创建MyFilter.java
编写MyFilter.java
filterType:返回一个字符串代表过滤器的类型,在zuul中定义了四种不同生命周期的过滤器类型,具体如下:
· pre:路由之前
· routing:路由之时
· post: 路由之后
· error:发送错误调用
· filterOrder:过滤的顺序
· shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
· run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问
package com.immo.filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; @Component public class MyFilter extends ZuulFilter{ @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); Object accessToken = request.getParameter("param"); if(accessToken == null) { ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { HttpServletResponse response = ctx.getResponse(); response.setCharacterEncoding("utf-8"); response.getWriter().write("沒有携带参数,拦截!"); }catch (Exception e){ e.printStackTrace(); } return null; } return null; } } |
测试,先后启动immo-eureka,immo-client,immo-feign,immo-zuul这四个项目:
访问刚刚访问过的接口,因为没有携带param接口给我们返回了提示信息,证明过滤了:
再次访问,携带param参数,正常获得数据: