• SpringCloud + Consul服务注册中心 + gateway网关


    1  启动Consul

    2  创建springcloud-consul项目及三个子模块

           2.1 数据模块consul-producer

           2.2 数据消费模块consul-consumer

           2.3 gateway网关模块

    3  测试及项目下载

      

    1、首先安装Consul并启动Consul,端口号为8500

    (为了安全起见, 需要设置consul 的token用于认证,  见https://www.cnblogs.com/wushengwuxi/articles/12840500.html

     在application.yml中添加spring.cloud.consul.discovery.acl-token属性, https://www.cnblogs.com/duanxz/p/7049350.html) 

    2、创建一个maven项目springcloud-consul,修改pom.xml添加SpringBoot及SpringCloud依赖(这里展示的是最后的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">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.test</groupId>
        <artifactId>springcloud-consul</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>consul-producer</module>
            <module>consul-consumer</module>
            <module>gateway-service</module>
        </modules>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
            <relativePath/>
        </parent>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-consul-discovery</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-consul-config</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>

    2.1  数据提供模块consul-producer

    创建数据提供服务模块consul-producer,修改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>springcloud-consul</artifactId>
            <groupId>com.test</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>consul-producer</artifactId>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>4.3.1</version>
            </dependency>
        </dependencies>
    
    </project>

    配置文件application.yml文件为:

    debug: false
    
    spring.aop.auto: true
    
    spring:
      application:
        name: data-producer
    
      cloud:
        consul:
          enabled: true
          host: localhost
          port: 8500
          discovery:
            enabled: true
            register: true    #是否将自身服务注册到consul中
            hostname: 127.0.0.1
            healthCheckPath: /actuator/health  #服务健康检查地址
            healthCheckInterval: 15s
            serviceName: ${spring.application.name}
            tags: test
            instanceId: ${spring.application.name}-${spring.cloud.client.ip-address}-${server.port}  # 服务id

    启动类DataProducerApplication

    package com.test;
    
    import cn.hutool.core.convert.Convert;
    import cn.hutool.core.thread.ThreadUtil;
    import cn.hutool.core.util.NetUtil;
    import cn.hutool.core.util.NumberUtil;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    import java.util.Scanner;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TimeoutException;
    
    @EnableDiscoveryClient
    @SpringBootApplication
    @EnableAutoConfiguration
    public class DataProducerApplication {
    
        public static void main(String[] args) {
    
            int port = 0;
            int defaultPort = 8080;
            int time = 5;
            Future<Integer> future = ThreadUtil.execAsync(() ->{
                int p = defaultPort;
                System.out.println(String.format("请于%d秒钟内输入端口号, 推荐  8080 、 8081  或者  8082,超过%d秒将默认使用 %d", time, time, defaultPort));
                Scanner scanner = new Scanner(System.in);
                while(true) {
                    String strPort = scanner.nextLine();
                    if(!NumberUtil.isInteger(strPort)) {
                        System.err.println("只能是数字");
                    } else {
                        p = Convert.toInt(strPort);
                        scanner.close();
                        break;
                    }
                }
                return p;
            });
            try{
                port=future.get(time, TimeUnit.SECONDS);
            }
            catch (InterruptedException | ExecutionException | TimeoutException e){
                port = defaultPort;
            }
    
            if(!NetUtil.isUsableLocalPort(port)) {
                System.err.printf("端口%d被占用了,无法启动%n", port );
                System.exit(1);
            }
    
            new SpringApplicationBuilder(DataProducerApplication.class).properties("server.port=" + port).run(args);
        }
    }

     DataController处理每一个请求

    package com.test.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    
    @RestController
    public class DataController {
    
        @RequestMapping("/**")
        public String get(HttpServletRequest request) {
            return String.format("实际响应地址:%s", request.getRequestURL().toString());
        }
    }

    2.2  数据消费模块consul-consumer

    使用LoadBalancerClient实现服务转发,即将服务映射到consul-producer服务

    修改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>springcloud-consul</artifactId>
            <groupId>com.test</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>consul-consumer</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
        </dependencies>
    
    </project>

    配置文件application.yml

    spring:
      application:
        name: data-consumer
      cloud:
        consul:
          host: 127.0.0.1
          port: 8500
          discovery:
            register: true
            hostname: 127.0.0.1
            healthCheckPath: /actuator/health
    server:
      port: 8090
    
    data-producer: data-producer

    启动类DataConsumerApplication

    package com.test;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    @EnableDiscoveryClient
    public class DataConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DataConsumerApplication.class, args);
        }
    }

    DataConsumerController处理请求

    package com.test.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.client.ServiceInstance;
    import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import javax.servlet.http.HttpServletRequest;
    
    @RestController
    public class DataConsumerController {
    
        @Value("${data-producer}")
        private String dataProducer;
    
        @Autowired
        private LoadBalancerClient loadBalancerClient;
    
        @RequestMapping("/data-api/**")
        public String test(HttpServletRequest request) {
            ServiceInstance serviceInstance = loadBalancerClient.choose(dataProducer);
    
            String result = new RestTemplate().getForObject(serviceInstance.getUri().toString() + request.getRequestURI().replace("data-api", ""),
                    String.class);
            System.out.println(result);
            return result;
        }
    }

    2.3 gateway网关实现服务转发

    创建gateway-service模块,修改pom.xml增加gateway所需依赖

    <?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>springcloud-consul</artifactId>
            <groupId>com.test</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>gateway-service</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
        </dependencies>
    
    
    </project>

    配置文件application.yml

    server:
      port: 8100
    
    spring:
      application:
        name: gateway-service
      cloud:
        gateway:
          routes:
            - id: data-service1  #请求 http://localhost:8100/data-service1/test会转发到data-producer服务,
              uri: lb://data-producer  #在服务注册中心找服务名为 data-producer的服务,
              predicates:
                - Path=/data-service1/**
              filters:
                - StripPrefix=1
            - id: data-service2  # 请求 http://localhost:8100/data-service2/test转发到 http://localhost:8080/test
              uri: http://localhost:8080
              predicates:
                - Path=/data-service2/**
              filters:
                - StripPrefix=1  #前缀, 在当前路径匹配中表示去掉第一个前缀 /data-service2
        consul:
          enabled: true
          host: localhost
          port: 8500
          discovery:
            enabled: true
            register: false    #是否将自身服务注册到consul中
            hostname: 127.0.0.1
            healthCheckPath: /actuator/health  #服务健康检查地址
            healthCheckInterval: 15s
            serviceName: ${spring.application.name}
            tags: test
            instanceId: ${spring.application.name}-${spring.cloud.client.ip-address}-${server.port}  # 服务id

    启动类GatewayServiceApplication

    package com.test;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    public class GatewayServiceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(GatewayServiceApplication.class, args);
        }
    }

    3、测试及项目下载

    首先启动consul,启动两个DataProducerApplication实例,端口号为8080、8081, 启动DataConsumerApplication及GatewayServiceApplication

    DataConsumerApplication服务

    在浏览器输入http://localhost:8090/data-api/test, 访问DataConsumerApplication服务,输出结果为: “实际响应地址:http://127.0.0.1:8081/test”  或  "实际响应地址:http://127.0.0.1:8080/test"

    GatewayServiceApplication服务

    转发格式见application.yml文件

    在浏览器中输入http://localhost:8100/data-service1/test, 访问GatewayServiceApplication同样 可以看到  有时访问8080端口的DataProducerApplication服务,有时访问8081端口的DataProducerApplication服务

    在浏览器中输入http://localhost:8100/data-service2/test, 实际响应的是8080端口的DataProducerApplication服务,

    项目下载

  • 相关阅读:
    Abstract与Virtual
    List 常用方法
    控制数据采样分布 计算概念
    中期答辩感想
    软件开发之团队理解
    详细设计理解
    竞赛系统需求分析
    软件代码规范之理解
    AngularJS 整理资料
    AngularJS合集
  • 原文地址:https://www.cnblogs.com/wushengwuxi/p/11585567.html
Copyright © 2020-2023  润新知