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

項目下載

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM