搭建Zuul网关

image.png

在上一个项目的configCenter父项目中新增maven Module子项目zuul_gateway;
该服务为网关服务,所有请求先经过该网关后,由网关负责去注册中心获取对应服务真实地址,然后在本地做负载均衡请求真实服务器地址。
本网关服务对外端口:8102
app-member会员服务端口:8101
app-order订单服务端口:8103
该网关服务需要将自己注册到eureka注册中心,所以需要EurekaServer服务。

image.png

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">
    <parent>
        <artifactId>configCenter</artifactId>
        <groupId>configCenter</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>zuul_gateway</artifactId>

    <dependencies>
        <!--spring-cloud2.0比较支持zuul网关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>
</project>

application.yml 文件内容:

server:
  port: 8102

###服务别名--该服务注册到服务中心的名称
spring:
  application:
    name: service-zuul
zuul:
  routes:
    ### 定义转发规则,这里的api-a是自定义的,也可以修改为api-member
    api-a:
      ### 客户端请求http://127.0.0.1/api-member开头的,都会转发到会员服务
      path: /api-member/**
      #这里的app-member是会员服务在注册中信中的别名
      #zuul网关默认整合ribbon,自动实现负载均衡轮训效果
      serviceId: app-member
    api-b:
      path: /api-order/**
      serviceId: app-order


eureka:
  client:
    serviceUrl:
      ###当前会员服务注册到eureka服务中心(所有eureka集群地址)
      defaultZone: http://eureka-server1:7100/eureka

项目启动 ZuulGatewayApplication.java

package zuul_gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
//@EnableEurekaClient 将当前服务注册到Eureka
@EnableEurekaClient
//开启Zuul网关代理
@EnableZuulProxy
public class ZuulGatewayApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(ZuulGatewayApplication.class, args);
    }
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(ZuulGatewayApplication.class);
    }
}

启动网关服务并测试

image.png
  • 启动网关服务之前,需要先启动如下服务:
    • springcloud-eureka-service 注册中心服务。端口:7100
    • api-member-service-impl 会员服务.端口:8101
    • api-order-service-impl 订单服务, 端口:8103
  • 启动本网关zuul_gateway服务,端口:8102
  • 访问EurekaServer:http://127.0.0.1:7100,可以看到会员服务订单服务网关服务,三个服务均已经注入到注册中心。
    image.png
  • 直接访问订单服务(不通过网关):http://127.0.0.1:8103:


    image.png
  • 直接访问会员服务(不通过网关):http://127.0.0.1:8101:


    image.png
  • 通过网关访问会员服务:http://127.0.0.1:8102/api-member/
    image.png
  • 通过网关访问订单服务:http://127.0.0.1:8102/api-order/
    image.png

在zuul_gateway网关项目中添加过滤器

  • 在网关中添加过滤器,过滤规则: 获取参数userToken, 如果该参数为空则直接返回.当然这是是一个演示,也可以过滤一些其他规则.
  • 在zuul_gateway项目中添加 TokenFilter.java过滤器.
package zuul_gateway;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * 网关token过滤器
 * @author liangxifeng
 * @date 2020-08-09
 */
@Component
public class TokenFilter extends ZuulFilter {
    //过滤器类型pre,表示请求之前执行
    @Override
    public String filterType() {
        return "pre";
    }

    //过滤器执行顺序,当一个请求在同一阶段存在多个过滤器的时候,多个过滤器执行顺序
    @Override
    public int filterOrder() {
        return 0;
    }

    //判断过滤器是否生效,这里return true生效
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 拦截业务逻辑代码
     * 所有通过网关的请求,都必须通过该方法验证,才能继续放行
     * 如果验证失败,则返回401
     */
    @Override
    public Object run() throws ZuulException {
        //案例:拦截所有服务接口,判断服务接口上是否有传递userToken参数
        //1. 获取上下文
        RequestContext currentContext = RequestContext.getCurrentContext();
        //2. 获取Request
        HttpServletRequest request = currentContext.getRequest();
        //3. 获取token
        String userToken = request.getParameter("userToken");
        if (StringUtils.isEmpty(userToken)) {
            //如果token为空,则网关直接返回
            currentContext.setSendZuulResponse(false);
            currentContext.setResponseBody("userToken is null");
            currentContext.setResponseStatusCode(401);
            return null;
        }
        //正常调用其他服务接口
        return null;
    }
}

动态Zuul网关路由转发

  • 以上Zuul路由转发规则只配置两两个 api-memberapi-order, 如果网关项目正在运行,需要新增路由规则,就需要修改配置文件,重启网关服务了. 这里配置一下动态读取配置文件. 不需要重启服务.

  • 也就是将路由配置信息作为配置文件service-zuul-dev.yml放到git版本库中,在git中新增zuul_config目录作为网关服务配置文件存储目录, 内容如下: git地址: https://github.com/liangxifeng833/gkconfig/blob/master/zuul-config/service-zuul-dev.yml

      zuul:
        routes:
          ### 定义转发规则,这里的api-a是自定义的,也可以修改为api-member
          api-a:
            ### 客户端请求http://127.0.0.1/api-member开头的,都会转发到会员服务
            path: /api-member/**
            #这里的app-member是会员服务在注册中心中的别名
            #zuul网关默认整合ribbon,自动实现负载均衡轮训效果
            serviceId: app-member
          api-b:
            path: /api-order/**
            serviceId: app-order
    
  • 修改pom.xml文件,新增分布式配置中心相关依赖

          <!-- 分布式配置中心相关依赖#################################start -->
          <!-- springCloud整合config-server分布式配置中心client -->
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-config-client</artifactId>
          </dependency>
          <!--actuaor监控中心,手动触发刷新本地读取git中配置文件缓存所用-->
          <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-actuator</artifactId>
          </dependency>
          <!-- 分布式配置中心相关依赖#################################end -->
    
  • 然后将zuul_gateway网关项目application.yml修改为bootstrap.yml, 因为 SpringCloud里面有个“启动上下文”,主要是用于加载远端的配置,也就是加载ConfigServer里面的配置,默认加载顺序为:加载bootstrap.里面的配置 --> 连接configserver,加载远程配置 --> 加载application.里面的配置; 总结:这里需要借助于“启动上下文”来处理加载远程配置;bootstrap.yml 内容如下:

      server:
        port: 8102
    
      ###服务别名--该服务注册到服务中心的名称
      spring:
        application:
          #这里的服务别名=要读取git的配置文件的服务名称
          #配置文件命名规范:服务名-环境.yml(service-zuul-dev.yml)
          name: service-zuul
        cloud:
          config:
            #读取配置文件的环境(service-zuul-dev.yml)中的dev
            profile: dev
            #读取配置文件服务的config-server环境
            #也就是配置中心服务端在eureka注册的服务别名
            discovery:
          service-id: config-server
          #开启读取权限
          enabled: true
    
      #actuaor监控中心,开启所有端点,手动触发刷新本地缓存读取最新git配置文件所用
      management:
        endpoints:
          web:
            exposure:
          include: "*"  # * 在yaml 文件属于关键字,所以需要加引号
      eureka:
        client:
          serviceUrl:
            ###当前会员服务注册到eureka服务中心(所有eureka集群地址)
            defaultZone: http://eureka-server1:7100/eureka/
    
  • 修改项目入口文件ZuulGatewayApplication, 新增方法如下:
    作用是修改git中配置文件信息后, 手动调用接口刷新网关读取远程配置文件信息所用.

              // zuul配置使用git中config实现实时更新
          @RefreshScope
          @ConfigurationProperties("zuul")
          public ZuulProperties zuulProperties() {
          return new ZuulProperties();
          }
    
  • 重启该项目后, 访问: http://127.0.0.1:8202/api-member?userToken=12, 如果能够正常访问就代表配置成功了.

  • 此时我们后端,开启两个member服务, 作为集群. zuul可以自动实现ribbon负载均衡. 以下两次请求代表分别请求到了两个会员服务(默认负载均衡为: 轮训算法)

    image.png

    image.png

我的视频总结地址:https://www.bilibili.com/video/BV1z64y1F727/
我的源代码地址:https://github.com/liangxifeng833/springcloud/tree/master/configCenter/zuul_gateway

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267