美文网首页
微服务 Spring Cloud Alibaba 项目搭建(五、

微服务 Spring Cloud Alibaba 项目搭建(五、

作者: 一介书生独醉江湖 | 来源:发表于2023-07-26 17:33 被阅读0次

    一、gateway 网关子模块创建

    1、右键项目 - New - Module

    image.png

    2、bootstrap.yml

    server:
      port: 8008
      servlet:
        context-path:
      tomcat:
        uri-encoding: utf-8
    spring:
      application:
        name: gateway   #唯一名称
      profiles:
        active: dev           # 运行环境
      freemarker:
        check-template-location: false
        prefer-file-system-access: false
    logging:      # logback 配置
      path: /usr/local/alibaba/logs/${spring.application.name}   # 保存日志文件目录路径
      level: # 日志级别
        org.springframework.web: DEBUG # 配置spring web日志级别
    
    

    3、bootstrap-dev.yml

    spring:
      cloud:
        sentinel:
          transport:
            port: 8719                                     # 默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
            dashboard: 127.0.0.1:9090                    # [sentinel]管理控制台地址
          eager: true
        nacos:
          discovery:
            server-addr: 192.168.0.119:8848                  # [nacos]的访问地址,根据上面准备工作中启动的实例配置
            namespace: 11ba48cc-9931-4760-bf58-7d3e2c99629c   # [nacos]test命名空间的ID
          config:
            server-addr: 192.168.0.119:8848                  # [nacos]的访问地址,根据上面准备工作中启动的实例配置
            namespace: 11ba48cc-9931-4760-bf58-7d3e2c99629c   # [nacos]test命名空间的ID
            group: DEFAULT_GROUP                              # [nacos]默认分组就是DEFAULT_GROUP,如果使用默认分组可以不配置
            file-extension: yml                               # [nacos]默认properties
        gateway:
          locator:
            enabled: true                 # 让gateway可以发现nacos中的微服务
          globalcors:                     # 网关cors跨域设置
            cors-configurations:
              '[/**]':                    # gateway网关上所有的uri都应用下面的跨域设置
                allowed-credentials: true # 允许携带认证信息
                allowed-origins:
                  - "*"                   # 允许所有来源进行跨域访问
                allowed-headers: "*"      # 允许跨域请求里的head字段,设置为*是全部
                allowed-methods:          # 允许跨域的方法
                  - GET
                  - POST
                  - PUT
                  - DELETE
                  - OPTIONS
                max-age: 3600
          routes:
            # oauth
            - id: oauth             # 当前路由的标识, 要求唯一
              uri: lb://oauth       # lb指的是从 nacos 中按照名称获取微服务,并遵循负载均衡策略
              predicates: # 断言(就是路由转发要满足的条件)
                - Path=/oauth/**    # 当请求路径满足Path指定的规则时,才进行路由转发
            # api
            - id: api               # 我们⾃定义的路由 ID,保持唯⼀
              uri: lb://api         # ⽬标服务地址(部署多实例)
              # gateway⽹关从服务注册中⼼获取实例信息然后负载后路由
              # 断⾔:路由条件,Predicate 接受⼀个输⼊参数,返回⼀个布尔值结果。该接⼝包含多种默认⽅法来将 Predicate 组合成其他复杂的逻辑(⽐如:与,或,⾮)。
              predicates:
                - Path=/api/**
              #filters: # 过滤器,请求在传递过程中可以通过过滤器对其进行一定的修改
              #  - StripPrefix=1    # 转发之前去掉1层路径
            # miniapp-oauth
            - id: miniapp-oauth
              uri: lb://miniapp-oauth
              predicates:
                - Path=/miniapp-oauth/**
            # miniapp-api
            - id: miniapp-api
              uri: lb://miniapp-api
              predicates:
                - Path=/miniapp-api/**
              #filters:
              #  - StripPrefix=1
            # callback
            - id: callback
              uri: lb://callback
              predicates:
                - Path=/callback/**
              #filters:
              #  - StripPrefix=1
    
    

    4、pom.xml

    <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">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>com.aydan</groupId>
            <artifactId>ali-cloud</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
    
        <artifactId>gateway</artifactId>
        <packaging>jar</packaging>
    
        <name>gateway</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-commons</artifactId>
            </dependency>
    
            <!--GateWay 网关-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
            <!--引入webflux-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-webflux</artifactId>
            </dependency>
            <!-- Actuator可以帮助你监控和管理Spring Boot应⽤-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
            <!--热部署-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            </dependency>
    
            <!--nacos config client 依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            </dependency>
            <!--链路追踪-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-sleuth</artifactId>
            </dependency>
    
            <!-- SpringCloud Alibaba Sentinel 流量监控控制台 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            </dependency>
            <!-- SpringCloud Alibaba Sentinel 网关限流 -->
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
            </dependency>
          <!-- SpringCloud Alibaba Sentinel 持久化 -->
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-datasource-nacos</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba.csp</groupId>
                <artifactId>sentinel-transport-simple-http</artifactId>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <!--编译插件-->
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>${maven.compiler.source}</source>
                        <target>${maven.compiler.target}</target>
                        <encoding>${project.build.sourceEncoding}</encoding>
                    </configuration>
                </plugin>
                <!--打包插件-->
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </project>
    
    

    5、GatewayApplication.java

    package com.aydan;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.core.env.Environment;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.util.TimeZone;
    
    /**
     * @Author ds
     * @Date 2023/7/27
     */
    @EnableDiscoveryClient
    @SpringBootApplication
    public class GatewayApplication {
    
        public static void main(String[] args) {
            TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
            ConfigurableApplicationContext application = SpringApplication.run(GatewayApplication.class, args);
            Environment environment = application.getEnvironment();
            String applicationName = environment.getProperty("spring.application.name");
            String port = environment.getProperty("server.port");
            String contextPath = environment.getProperty("server.servlet.context-path");
            System.out.println("---------------------------------------------------------->");
            System.out.println(" :: ServletInitializer 启动:" + applicationName);
            String localHost;
            try {
                localHost = InetAddress.getLocalHost().getHostAddress();
                System.out.println("\t\t http://" + localHost + ":" + port + "" + contextPath + "");
                System.out.println("\t\t http://127.0.0.1:9090");
            } catch (UnknownHostException e) {
                System.out.println("\t\t " + e.getMessage());
                e.printStackTrace();
            }
            System.out.println("<----------------------------------------------------------");
        }
    
    }
    
    

    6、CorsConfig.java

    package com.aydan.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.http.HttpMethod;
    import org.springframework.stereotype.Component;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.reactive.CorsWebFilter;
    import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
    
    /**
     * @Author ds
     * @Date 2023/7/27
     */
    @Component
    public class CorsConfig {
    
        @Bean
        public CorsWebFilter corsWebFilter() {
    
            /**
             * 返回一个CorsWebFilter ,构造其中需要传入连个形参,均为接口,可以直接new 接口
             * 是借口可以使用它的实现类来处理
             */
            UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
    
            //构建CorsConfiguration
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedOrigin("*");
            corsConfiguration.addAllowedMethod(HttpMethod.DELETE);
            corsConfiguration.addAllowedMethod(HttpMethod.PUT);
            corsConfiguration.addAllowedMethod(HttpMethod.OPTIONS);
            corsConfiguration.addAllowedMethod(HttpMethod.GET);
            corsConfiguration.addAllowedMethod(HttpMethod.POST);
            corsConfiguration.addAllowedMethod(HttpMethod.HEAD);
            corsConfiguration.addAllowedHeader("*");
            // 允许cookie跨域
            corsConfiguration.setAllowCredentials(true);
    
            urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsWebFilter(urlBasedCorsConfigurationSource);
        }
    
    }
    
    

    7、GatewayConfig.java

    package com.aydan.config;
    
    import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
    import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
    import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
    import com.aydan.core.BaseResponse;
    import org.springframework.cloud.gateway.filter.GlobalFilter;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.codec.ServerCodecConfigurer;
    import org.springframework.web.reactive.function.BodyInserters;
    import org.springframework.web.reactive.function.server.ServerResponse;
    import org.springframework.web.reactive.result.view.ViewResolver;
    
    import javax.annotation.PostConstruct;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    
    /**
     * @Author ds
     * @Date 2023/7/27
     */
    @Configuration
    public class GatewayConfig {
    
        private final List<ViewResolver> viewResolvers;
        private final ServerCodecConfigurer serverCodecConfigurer;
    
        public GatewayConfig(List<ViewResolver> viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {
            this.viewResolvers = viewResolvers;
            this.serverCodecConfigurer = serverCodecConfigurer;
        }
    
        /**
         * 初始化一个限流的过滤器
         * @return
         */
        @Bean
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public GlobalFilter sentinelGatewayFilter() {
            return new SentinelGatewayFilter();
        }
    
    
        /**
         * 配置初始化的限流参数
         */
        @PostConstruct
        public void initGatewayRules() {
            Set<GatewayFlowRule> rules = new HashSet<>();
            // 分别给指定的资源 配置限流
            // GatewayFlowRule 资源名称,对应路由id     setCount  限流阈值   setIntervalSec 统计时间窗口,单位是秒,默认是 1 秒
            // 简单来说就是     如果Count=1    IntervalSec=1  那么一秒钟只允许访问一次   (用于测试)
            // 如果Count=5    IntervalSec=2  那么2秒钟只允许访问5次   (用于测试)
            // 如果Count=60   IntervalSec=3  那么3秒钟只允许访问60次 也就是1秒20次  一般用于生产(一般够了)
            // 如果是商城网站那么Count和IntervalSec 这个需要计算平均每天每秒最大的请求量是多少然后在设置
            int count = 50;
            int intervalSec = 5;
    
            // 设置指定路由的限流
            rules.add(new GatewayFlowRule("api").setCount(count).setIntervalSec(intervalSec));
            rules.add(new GatewayFlowRule("miniapp-api").setCount(count).setIntervalSec(intervalSec));
    
            GatewayRuleManager.loadRules(rules);
    
        }
    
    
        /**
         * 配置限流的异常处理器
         * @return
         */
        @Bean
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
            return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
        }
    
        /**
         * 自定义限流异常页面
         */
        @PostConstruct
        public void initBlockHandlers() {
            BlockRequestHandler blockRequestHandler = (serverWebExchange, throwable) -> {
                BaseResponse response = new BaseResponse();
                response.setStatus(429);
                response.setMessage("请求过于频繁");
                return ServerResponse.status(HttpStatus.OK).
                        contentType(MediaType.APPLICATION_JSON_UTF8).
                        body(BodyInserters.fromObject(response));
            };
            GatewayCallbackManager.setBlockHandler(blockRequestHandler);
        }
    }
    
    

    8、BaseResponse.java

    package com.aydan.core;
    
    import lombok.Data;
    
    import java.io.Serializable;
    
    /**
     * @Author ds
     * @Date 2023/7/27
     */
    @Data
    public class BaseResponse implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        protected int status;
        protected String message;
        protected String recvTime;
        protected String respTime;
    }
    
    

    9、Nacos配置

    image.png
    image.png
    参考:
    https://www.jianshu.com/p/552416053ff1
    

    相关文章

      网友评论

          本文标题:微服务 Spring Cloud Alibaba 项目搭建(五、

          本文链接:https://www.haomeiwen.com/subject/ptdkpdtx.html