搭建Zuul网关

image.png

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

image.png

pom.xml文件内容:



    
        configCenter
        configCenter
        1.0-SNAPSHOT
    
    4.0.0
    zuul_gateway

    
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-zuul
        
    

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_gateway服务, 再次通过网关访问会员服务, http://127.0.0.1:8102/api-member, 如果没有userToken参数,回直接返回:
    image.png
  • 在请求中添加userToken参数, 就可以直接访问到 会员服务了. http://127.0.0.1:8102/api-member?userToken=123456
    image.png

动态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文件,新增分布式配置中心相关依赖

          
          
          
              org.springframework.cloud
              spring-cloud-config-client
          
          
          
              org.springframework.boot
              spring-boot-starter-actuator
          
          
    
  • 然后将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

你可能感兴趣的:(搭建Zuul网关)