2 微服务实战系列 - SpringCloud服务网关

**服务网关解决问题:
1 内外网隔离,统一对外访问,统一权限控制,资源授权访问
2 自动路由,用户访问路由规则分发到响应服务**

1 pom配置

 <!-- spring boot的parent 配置文件,有大部分spring boot需要用的Jar包 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.6.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.7</java.version>
    </properties>

    <profiles>
        <profile>
            <id>www</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <!-- 系统参数 -->
                <server.mode>false</server.mode>
                <error.subject>gateway-www</error.subject>

                <!-- 服务注册 -->
                <url.defaultZone>http://register.totodi.com/eureka/</url.defaultZone>
            </properties>
        </profile>
    </profiles>

    <dependencies>
        <!-- eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

        <!-- 网关 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

        <!-- spring boot-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions><!-- 去掉默认配置 -->  
                <exclusion>  
                    <groupId>org.springframework.boot</groupId>  
                    <artifactId>spring-boot-starter-logging</artifactId>  
                </exclusion>  
            </exclusions>  
        </dependency>

        <!-- 引入log4j2依赖 -->  
        <dependency> 
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-log4j2</artifactId>  
        </dependency>

        <!-- 邮件发送 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <!-- 模板引擎 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

        <!-- fastjson依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.31</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Dalston.SR2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- spring boot的maven打包插件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <executable>true</executable>
                </configuration>
            </plugin>

            <plugin>
                   <artifactId>maven-resources-plugin</artifactId>
                   <configuration>
                       <encoding>utf-8</encoding>
                       <useDefaultDelimiters>true</useDefaultDelimiters>
                   </configuration>
               </plugin>
        </plugins>

        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>

        <finalName>gateway</finalName><!-- 包名 -->
    </build>

2 程序设置

  • 2.1 入口程序
@Autowired DiscoveryClient discoveryClient;

    @Bean
    public AccessFilter accessFilter() {
        return new AccessFilter();
    }

    @Bean
    public ErrorFilter errorFilter() {
        return new ErrorFilter();
    }

    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        builder.sources(this.getClass());
        return super.configure(builder);
    }

    @Bean 
    public MultipartConfigElement multipartConfigElement() { 
        MultipartConfigFactory factory = new MultipartConfigFactory();
        // 设置文件大小限制 ,超了,页面会抛出异常信息,这时候就需要进行异常信息的处理了;
        factory.setMaxFileSize("500MB"); //KB,MB
        // 设置总上传数据总大小
        factory.setMaxRequestSize("500MB"); 
        return factory.createMultipartConfig(); 
    }

    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }

    @RequestMapping("/info")
    public String info() {
        List<String> services = discoveryClient.getServices();

        Map<String, Object> re = Maps.newHashMap();
        for(String temp : services){
            re.put(temp, discoveryClient.getInstances(temp));
        }
        return JSON.toJSONString(services);
    }
  • 2.2 filter注入
private static final Logger LOGGER = LoggerFactory.getLogger(AccessFilter.class);

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();

        LOGGER.info(String.format("send %s request to %s", request.getMethod(), request.getRequestURL().toString()));

        LOGGER.info("isDispatcherServletRequest:{}", RequestUtils.isDispatcherServletRequest());
        LOGGER.info("isZuulServletRequest:{}", RequestUtils.isZuulServletRequest());

        // 判断是否OPTIONS请求
        if(request.getMethod().equals("OPTIONS")){
            return null;
        }
// 参数必传
        if (StringUtils.isEmpty(mac) || StringUtils.isEmpty(os) || StringUtils.isEmpty(version) || StringUtils.isEmpty(timestamp) || StringUtils.isEmpty(sign)) {
            LOGGER.warn("access token is empty!");
            String body = JSON.toJSONString(Message.failure(ApiCodeEnum.NOT_AUTHORIZED));
            ctx.setSendZuulResponse(false);
            ctx.setResponseBody(body);
            ctx.setResponseStatusCode(401);
            return null;
        }

        // 签名算法
        String signStr = EncryptUtils.encodemd5(timestamp.trim()).substring(11, 17);
        if (!signStr.equalsIgnoreCase(sign.trim())) {
            LOGGER.warn("access token wrong!");
            String body = JSON.toJSONString(Message.failure(ApiCodeEnum.NOT_AUTHORIZED));
            ctx.setSendZuulResponse(false);
            ctx.setResponseBody(body);
            ctx.setResponseStatusCode(401);
          return null;
        }
        LOGGER.info("access token ok");

        return null;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public String filterType() {
        return "pre";
    }

3 应用配置

server.port=8002
spring.application.name=gateway

#\u6ce8\u518c\u670d\u52a1\u5668\u7684\u5730\u5740\uff1a\u670d\u52a1\u63d0\u4f9b\u8005\u548c\u670d\u52a1\u6d88\u8d39\u8005\u90fd\u8981\u4f9d\u8d56\u8fd9\u4e2a\u5730\u5740
eureka.client.serviceUrl.defaultZone=http://register.shulai8.com/eureka/

#spring cloud eureka IP\u6ce8\u518c\u800c\u4e0d\u662f hostName\u6ce8\u518c\u3002Spring\u5c31\u4f1a\u81ea\u52a8\u4e3a\u6211\u4eec\u83b7\u53d6\u7b2c\u4e00\u4e2a\u975e\u56de\u73afIP\u5730\u5740
eureka.instance.prefer-ip-address=true

#\u90ae\u4ef6\u914d\u7f6e
spring.mail.host=smtp.exmail.qq.com
[email protected]
spring.mail.password=iiu7mBC6ddj0Yiii
spring.mail.default-encoding=UTF-8

# \u9879\u76eecontextPath
server.context-path=/
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**

# URI\u7f16\u7801
server.tomcat.uri-encoding=UTF-8
server.tomcat.access-log-enabled=true
logging.config=classpath:log4j2.xml

猜你喜欢

转载自blog.csdn.net/wolfjson/article/details/78501994