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服务,

项目下载

原文地址:https://www.cnblogs.com/wushengwuxi/p/11585567.html