【前面的話】書接上文,前面已經講過了SpringCloud的注冊中心Eureka、Ribbon和Feign等等,如果有不清楚的也可以去看看我的微服務系列文章,這篇文章我要說的是微服務中的網關,
壹、Zuul的簡介
Zuul的主要功能是路由轉發和過濾器,路由功能是微服務的一部分,比如/api/user轉發到到user服務,/api/shop轉發到到shop服務,zuul默認和Ribbon結合實作了負載均衡的功能,
zuul有以下功能:
Authentication
Insights
Stress Testing
Canary Testing
Dynamic Routing
Service Migration
Load Shedding
Security
Static Response handling
Active/Active traffic management
貳、準備作業
新建一個feign子工程lovin-cloud-zuul,用于后面的操作,下面是主要的pom依賴:
<parent>
<artifactId>lovincloud</artifactId>
<groupId>com.eelve.lovincloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lovin-cloud-zuul</artifactId>
<packaging>jar</packaging>
<name>lovincloudzuul</name>
<version>0.0.1</version>
<description>zuul</description>
<dependencies>
<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-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 這里為了安全,我這里還是添加spring-boot-starter-security,同時配置路由規則發送/api-ribbon/打頭開始的服務轉發到lovinribbonclient而發送/api-feign/打頭的服務轉發到lovinfeignclient,可以看出這里是配置相應的路由規則,
server:
port: 8882 # 服務埠號
spring:
application:
name: lovincloudzuul # 服務名稱
security:
basic:
enabled: true
user:
name: lovin
password: ${REGISTRY_SERVER_PASSWORD:lovin}
zuul:
routes:
api-ribbon:
path: /api-ribbon/**
serviceId: lovinribbonclient
api-feign:
path: /api-feign/**
serviceId: lovinfeignclient
eureka:
client:
serviceUrl:
defaultZone: http://lovin:lovin@localhost:8881/eureka/ # 注冊到的eureka服務地址
instance:
leaseRenewalIntervalInSeconds: 10
health-check-url-path: /actuator/health
metadata-map:
user.name: lovin
user.password: lovin
- 配置spring-boot-starter-security,這里為了方便我這里放開所有請求
package com.eelve.lovin.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
/**
* @ClassName WebSecurityConfig
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/18 12:17
* @Version 1.0
**/
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll()
.and().csrf().disable();
}
}
- 在主類上添加@EnableZuulProxy ,當然也需要注冊到注冊中心:
package com.eelve.lovin;
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;
/**
* @ClassName LovinEurekaClientApplication
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/15 16:37
* @Version 1.0
**/
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class LovinCloudZuulApplication {
public static void main(String[] args) {
SpringApplication.run(LovinCloudZuulApplication.class,args);
}
}
- 這里為了方便測驗,這里配置相應的過濾規則:
package com.eelve.lovin.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* @ClassName MyFilter
* @Description TDO
* @Author zhao.zhilue
* @Date 2019/8/18 12:44
* @Version 1.0
**/
@Component
@RefreshScope // 使用該注解的類,會在接到SpringCloud配置中心配置重繪的時候,自動將新的配置更新到該類對應的欄位中,
@Slf4j
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() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
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;
}else if(!accessToken.equals("lovin")){
log.warn("token is not correct");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(403);
try {
ctx.getResponse().getWriter().write("token is not correct");
}catch (Exception e){}
return null;
}
log.info("ok");
return null;
}
}
filterType:回傳一個字串代表過濾器的型別,在zuul中定義了四種不同生命周期的過濾器型別,具體如下:
pre:路由之前
routing:路由之時
post: 路由之后
error:發送錯誤呼叫
filterOrder:過濾的順序
shouldFilter:這里可以寫邏輯判斷,是否要過濾,本文true,永遠過濾,
run:過濾器的具體邏輯,可用很復雜,包括查sql,nosql去判斷該請求到底有沒有權限訪問,
叁、啟動測驗
- 依次啟動eureka的服務端和兩個客戶端和lovin-feign-client、lovin-ribbon-client,以及新建的lovin-cloud-zuul
- 然后訪問http://localhost:8882/api-feign/getHello和http://localhost:8882/api-ribbon/hello,然后我們可以帶上token訪問來驗證過濾器








肆、網路架構
- 我們可以看到我們呼叫的服務不再是像再上一篇文章中的直接訪問對應的服務,而是通過feign的Ribbon的負載均衡的去呼叫的,而且這里說明一點,Ribbon的默認機制是輪詢,

- 最后的最后是本博客的原始碼,歡迎關注這一套SpringCloud的實踐
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/243471.html
標籤:Java
上一篇:hadoop安裝解決之道
