話不多說,先上圖(圖是醜陋了點,大家別介意哈),這幅圖是我根據公司現有的業務設計出來的一個簡單的基於springcloud微服務架構圖。
在springcloud微服務體系中,我們一般不對外直接暴露服務層的接口,而是中間通過一層代理進行中轉,這層代理的好處一個是對外可以隱藏我們內部具體服務的接口,另一個就是我們非常重要的服務的負載均衡,在上圖中客戶端的所有請求先經過nginx(Nginx集羣)經由nginx代理轉發後進入springcloud的zuul(zuul集羣)路由網關服務,由zuul再去對應具體的服務;我們的所有服務均統一註冊到高可用的服務註冊發現(eureka server)集羣中。
首先介紹一下zuul的功能:
zuul的主要功能是路由轉發和過濾器。路由功能是微服務的一部分,比如/frnt轉發到到frnt服務,/portal轉發到portal服務。zuul默認和Ribbon結合實現了負載均衡的功能。
好啦,正式開工!
1.首先創建一個項目xx-zuul(名字任意取),引入相關依賴(spring-cloud-starter-netflix-zuul):
<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-zuul</artifactId> </dependency> <!--eureka client--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>1.4.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
2.打開application-dev.properties並加入以下內容:
#端口 server.port=8763 #實例名 spring.application.name=xx-zuul #註冊中心 eureka.server.host=localhost eureka.server.port=8761 eureka.client.service-url.defaultZone=http://${eureka.server.host}:${eureka.server.port}/eureka/ #路由規則配置 #攔截路徑 zuul.routes.demo-springboot.path=/demo/** #eureka中註冊的實例名 zuul.routes.demo-springboot.serviceId=demo-springboot #實際訪問時去除前綴(即:經過zuul轉發後會去除掉demo前綴) zuul.routes.demo-springboot.stripPrefix=true #連接超時時間 zuul.host.connect-timeout-millis=15000 zuul.host.socket-timeout-millis=10000 #log level logging.level.root=debug #開啓eureka client健康檢查 eureka.client.healthcheck=true # 續約到期時間(默認90秒) eureka.instance.lease-expiration-duration-in-seconds=30 # 續約更新時間間隔(默認30秒) eureka.instance.lease-renewal-interval-in-seconds=10
3.開啓zuul代理註解@EnableZuulProxy
@EnableZuulProxy @EnableEurekaClient @SpringBootApplication public class Xsignal2ZuulApplication { public static void main(String[] args) { SpringApplication.run(Xsignal2ZuulApplication.class, args); } }
4.最後啓動xx-zuul服務,demo-springboot服務,在eureka控制面板查看:
打開瀏覽器準備訪問zuul代理:
看到如圖結果表示我們的zuul代理已經生效,成功訪問到了demo-springboog項目,慶賀一下吧!
另外,文章開頭說道zuul支持過濾功能,即我們可以通過自定義filter繼承自ZuulFilter即可:
@Component public class MyFilter extends ZuulFilter { /*filterType:返回一個字符串代表過濾器的類型,在zuul中定義了四種不同生命週期的過濾器類型,具體如下: pre:路由之前 routing:路由之時 post: 路由之後 error:發送錯誤調用 filterOrder:過濾的順序 shouldFilter:這裏可以寫邏輯判斷,是否要過濾,本文true,永遠過濾。 run:過濾器的具體邏輯。可用很複雜,包括查sql,nosql去判斷該請求到底有沒有權限訪問。 */ private static Logger log = LoggerFactory.getLogger(MyFilter.class); @Override public String filterType() { return FilterConstants.PRE_TYPE; } @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("token"); if(accessToken == null) { log.warn("token is empty"); ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(401); try { ctx.getResponse().getWriter().write("token is empty"); }catch (Exception e){} return null; } return null; } }在filter中我們可以自定義需要過濾的請求,攔截非法請求,權限認證,頻控,限流等操作!