【前面的話】書接上文,前面已經講過了SpringCloud的註冊中心Eureka、Ribbon和Feign等等,若是有不清楚的也能夠去看看個人微服務系列文章。這篇文章我要說的是微服務中的網關。java
Zuul的主要功能是路由轉發和過濾器。路由功能是微服務的一部分,好比/api/user轉發到到user服務,/api/shop轉發到到shop服務。zuul默認和Ribbon結合實現了負載均衡的功能。git
zuul有如下功能:github
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依賴:web
<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>
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
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(); } }
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去判斷該請求到底有沒有權限訪問。