zoukankan      html  css  js  c++  java
  • 网关Zuul使用记录

    前奏

    最近公司需求网关,就选择了zuul。就使用了一下,在这里记录下使用过程中,遇到的一些常见的
    问题和用法。并且本次使用注册中心是基于zk,所以和大路上使用eureka是不同的,并且网上关于
    使用zk的资料相对较少!鉴于spring cloud 已经不再持续,建议大家选择gateway。
    

    pom依赖

    <properties>
    	<java.version>1.8</java.version>
    	<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
    </properties>
    

    主要依赖:

    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
    </dependency>
    <dependency>
    	<groupId>org.apache.zookeeper</groupId>
    	<artifactId>zookeeper</artifactId>
    </dependency>
    <dependency>
    	<groupId>com.101tec</groupId>
    	<artifactId>zkclient</artifactId>
    	<optional>true</optional>
    </dependency>
    <!-- 除此外还需要springboot web 、mysql、mybatis、lombok等依赖自行添加 -->
    
    

    注册中心

    application.properties

    spring.cloud.zookeeper.connect-string=zk地址
    spring.cloud.zookeeper.discovery.instance-port=${server.port}
    zuul.host.connection-request-timeout-millis=3000
    #spring.cloud.zookeeper.base-sleep-time-ms=10
    #不向zookeeper注册
    #spring.cloud.zookeeper.discovery.register=false
    # retry
    zuul.retryable=false
    
    # 超时设置,url生效
    zuul.host.connect-timeout-millis=10000
    zuul.host.socket-timeout-millis=10000
    # 超时设置,serviceId生效
    hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
    ribbon.ReadTimeout=30000
    ribbon.SocketTimeout=30000
    
    zuul.add-host-header=true
    zuul.strip-prefix=true
    

    动态加载路由规则

    实体对象:

    @Data
    public class ZuulRouteRule implements Serializable {
        /**
         * 主键ID
         */
        private Integer id;
    
        /**
         * 请求路径
         */
        private String path;
    
        /**
         * 服务提供者编码
         */
        private String serviceId;
    
        /**
         * 路由地址
         */
        private String url;
    
        /**
         * 是否增加前缀,0:否 1:是
         */
        private Boolean stripPrefix;
    
        /**
         * 是否重试, 0:否 1:是
         */
        private Boolean retryable;
    
        /**
         * 是否生效,0:生效 1:失效
         */
        private Boolean enabled;
    
        /**
         * 规则说明
         */
        private String description;
    
        /**
         * 创建时间
         */
        private Date createTime;
    
        /**
         * 创建人
         */
        private String createUser;
    
        /**
         * 更新时间
         */
        private Date updateTime;
    
        /**
         * 更新人
         */
        private String updateUser;
    
        private static final long serialVersionUID = 1L;
    }
    

    DAO层:

    public interface ZuulRouteRuleMapper{
        List<ZuulRouteRule> queryZuulRulesByCondition(ZuulRouteRule param);
    }
    

    Service接口

    public interface ZuulRouteRuleService {
        Map<String, ZuulProperties.ZuulRoute> getAllEnabledRules();
    }
    
    @Service
    public class ZuulRouteRuleServiceImpl implements ZuulRouteRuleService {
    
        @Autowired
        private ZuulRouteRuleMapper zuulRouteRuleMapper;
    
        @Override
        public Map<String, ZuulProperties.ZuulRoute> getAllEnabledRules() {
            Map<String, ZuulProperties.ZuulRoute> routes = new LinkedHashMap<>();
    
            ZuulRouteRule param = new ZuulRouteRule();
            param.setEnabled(true);
            List<ZuulRouteRule> zuulRouteRuleList = zuulRouteRuleMapper.queryZuulRulesByCondition(param);
            zuulRouteRuleList.forEach(routeRule -> {
                if (StringUtils.isEmpty(routeRule.getPath())) {
                    return;
                }
                ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
                BeanUtils.copyProperties(routeRule, zuulRoute);
                zuulRoute.setId(String.valueOf(routeRule.getId()));
                routes.put(zuulRoute.getPath(), zuulRoute);
            });
            return routes;
        }
    }
    

    动态路由加载

    @Slf4j
    public class DynamicZuulRouteLocator  extends SimpleRouteLocator implements RefreshableRouteLocator {
    
        private static final String SLASH = "/";
    
        @Autowired
        private ZuulProperties properties;
    
        @Autowired
        private ZuulRouteRuleService zuulRouteRuleService;
    
        public DynamicZuulRouteLocator(String servletPath, ZuulProperties properties) {
            super(servletPath, properties);
            this.properties = properties;
        }
    
        @Override
        public void refresh() {
            doRefresh();
        }
    
        @Override
        protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
            LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<>();
            routesMap.putAll(super.locateRoutes());
            Map<String, ZuulProperties.ZuulRoute> dbRoutesMap = zuulRouteRuleService.getAllEnabledRules();
            if(log.isInfoEnabled()){
                log.info("加载数据条目:{}",dbRoutesMap.size());
            }
    
            if (null != dbRoutesMap && !dbRoutesMap.isEmpty()) {
                routesMap.putAll(dbRoutesMap);
            }
    
            LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
            routesMap.forEach((key, value) -> {
                String path = key;
                if (!path.startsWith(SLASH)) {
                    path = SLASH + path;
                }
                if (StringUtils.hasText(this.properties.getPrefix())) {
                    path = this.properties.getPrefix() + path;
                    if (!path.startsWith(SLASH)) {
                        path = SLASH + path;
                    }
                }
                values.put(path, value);
            });
            return values;
        }
    }
    

    JavaConfig 加载bean

    @Configuration
    public class DynamicZuulConfig {
    
        @Bean
        public DynamicZuulRouteLocator routeLocator(ZuulProperties zuulProperties,ServerProperties serverProperties) {
            return new DynamicZuulRouteLocator(
                    serverProperties.getServlet().getContextPath(), zuulProperties);
        }
    }
    

    springboot启动类:

    @EnableZuulProxy
    @EnableDiscoveryClient
    @SpringBootApplication
    @MapperScan("com.demo.gateway.dao")
    public class GatewayApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }
    
        @Bean
        public AuthenticationFilter getAuthFilter(){
            return new AuthenticationFilter();
        }
    
    }
    

    自动刷新

    定时刷新

    @Configuration
    @Slf4j
    public class ScheduleZuulRulesListener implements ApplicationListener<ContextRefreshedEvent> {
    
        private static ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
    
        @Autowired
        private ZuulHandlerMapping zuulHandlerMapping;
    
        @Override
        public void onApplicationEvent(ContextRefreshedEvent applicationEvent) {
            service.scheduleAtFixedRate(() -> {
                if(log.isInfoEnabled()) {
                    log.info("刷新zuul配置信息开始");
                }
                try {
                    zuulHandlerMapping.setDirty(true);
                } catch (Exception e) {
                    log.error("刷新Zuul规则配置报错:{}",e.getMessage());
                }
    
                if(log.isInfoEnabled()) {
                    log.info("刷新zuul配置信息结束");
                }
            },10,10,TimeUnit.SECONDS);
    
        }
    }
    

    其他服务集成网关

    待补充

    集成swagger

    待补充

  • 相关阅读:
    选择屏幕加功能码
    alv 列标题
    指针引用的学习
    CM3中数据传输对齐/非对齐方式
    perl学习笔记之:模式匹配,模块,文档
    PERL学习之模式匹配
    perl:split函数用法
    perl:_DATA_ _LINE_ _FILE_
    CVS update常用技巧
    cvs 文件无法上传debug
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608351.html
Copyright © 2011-2022 走看看