Bootstrap

项目集成OpenFeign + cloud整体测试

1.环境搭建

1.创建模块 sunrays-common-cloud-openfeign-starter

CleanShot 2025-01-08 at 12.10.34@2x

2.目录结构

CleanShot 2025-01-08 at 12.19.01@2x

3.OpenFeignAutoConfiguration.java 自动配置类
package com.sunxiansheng.cloud.openfeign.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

/**
 * Description: OpenFeign 自动配置类
 *
 * @Author sun
 * @Create 2025/1/8 12:13
 * @Version 1.0
 */
@Configuration
@Slf4j
public class OpenFeignAutoConfiguration {

    /**
     * 自动配置成功日志
     */
    @PostConstruct
    public void logConfigSuccess() {
        log.info("OpenFeignAutoConfiguration has been loaded successfully!");
    }
}
4.spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.sunxiansheng.cloud.openfeign.config.OpenFeignAutoConfiguration
5.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>sunrays-common-cloud-openfeign-starter</artifactId>

    <dependencies>
        <!-- openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <!-- 排除logging -->
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- openfeign的负载均衡器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- Nacos的服务发现 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
</project>

2.sunrays-common-cloud 模块整体测试

1.创建demo模块

CleanShot 2025-01-08 at 12.31.46@2x

2.新建三个服务都注册到Nacos
1.项目结构

CleanShot 2025-01-08 at 12.49.56@2x

2.sunrays-common-cloud-base-starter 的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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-demo</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>sunrays-common-cloud-base-starter</artifactId>
    <packaging>pom</packaging>
    <description>对spring-cloud的常用组件gateway、nacos、openfeign进行统一测试</description>
    <modules>
        <module>gateway</module>
        <module>service-a</module>
        <module>service-b</module>
    </modules>

    <dependencies>
        <!-- nacos -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>sunrays-common-cloud-nacos-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>
</project>
3.gateway
1.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud-base-starter</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>gateway</artifactId>
</project>
2.application.yml
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      discovery:
        enabled: true # 启用服务发现
        server-addr:  # Nacos地址
sun-rays:
  log4j2:
    home: /Users/sunxiansheng/IdeaProjects/sunrays-framework/sunrays-demo/sunrays-common-cloud-base-starter/gateway/logs # 日志根目录(默认./logs)
    module: sunrays-demo/sunrays-common-cloud-base-starter/gateway # 模块根目录从仓库根目录开始(默认defaultModule)
server:
  port: 8081
3.GateWayApplication.java
package com.sunxiansheng.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description: GateWay 启动类
 *
 * @Author sun
 * @Create 2025/1/8 12:41
 * @Version 1.0
 */
@SpringBootApplication
public class GateWayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GateWayApplication.class, args);
    }
}
4.service-a
1.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud-base-starter</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>service-a</artifactId>
</project>
2.application.yml
spring:
  application:
    name: service-a # 服务名称
  cloud:
    nacos:
      discovery:
        enabled: true # 启用服务发现
        server-addr:  # Nacos地址
sun-rays:
  log4j2:
    home: /Users/sunxiansheng/IdeaProjects/sunrays-framework/sunrays-demo/sunrays-common-cloud-base-starter/service-a/logs # 日志根目录(默认./logs)
    module: sunrays-demo/sunrays-common-cloud-base-starter/service-a # 模块根目录从仓库根目录开始(默认defaultModule)
server:
  port: 8082
3.ServiceAApplication.java
package com.sunxiansheng.serviceA;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description: ServiceA 启动类
 *
 * @Author sun
 * @Create 2025/1/8 12:42
 * @Version 1.0
 */
@SpringBootApplication
public class ServiceAApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceAApplication.class, args);
    }
}
5.service-b
1.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud-base-starter</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>service-b</artifactId>
</project>
2.application.yml
spring:
  application:
    name: service-b # 服务名称
  cloud:
    nacos:
      discovery:
        enabled: true # 启用服务发现
        server-addr:  # Nacos地址
sun-rays:
  log4j2:
    home: /Users/sunxiansheng/IdeaProjects/sunrays-framework/sunrays-demo/sunrays-common-cloud-base-starter/service-b/logs # 日志根目录(默认./logs)
    module: sunrays-demo/sunrays-common-cloud-base-starter/service-b # 模块根目录从仓库根目录开始(默认defaultModule)
server:
  port: 8083
3.ServiceBApplication.java
package com.sunxiansheng.serviceB;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description: ServiceB 启动类
 *
 * @Author sun
 * @Create 2025/1/8 12:42
 * @Version 1.0
 */
@SpringBootApplication
public class ServiceBApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceBApplication.class, args);
    }
}
6.全部启动,成功注册到Nacos

CleanShot 2025-01-08 at 12.54.10@2x

3.配置GateWay
1.目录结构

CleanShot 2025-01-08 at 13.11.32@2x

2.gateway
1.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud-base-starter</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>gateway</artifactId>

    <dependencies>
        <!-- gateway -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>sunrays-common-cloud-gateway-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>
</project>
2.application.yml 配置路由到两个模块
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      discovery:
        enabled: true # 启用服务发现
        server-addr: # Nacos地址
    gateway:
      routes:
        # 请求到oss模块的规则是:GateWay的ip+端口号/oss/上下文路径+资源路径,而/oss的前缀会在真正转发的时候被去掉 也就是真正请求的完整路径是:GateWay的ip+端口号/上下文路径+资源路径
        - id: service-a # 路由ID,唯一即可
          uri: lb://service-a # 转发到的后端服务的服务名,需要与Nacos中注册的服务名一致
          predicates:
            - Path=/service-a/** # 断言,表示请求路径匹配/oss/**的请求将会被转发到后端服务
          filters:
            - StripPrefix=1 # 表示在将请求转发到后端服务之前,去掉路径
        # 请求到oss模块的规则是:GateWay的ip+端口号/oss/上下文路径+资源路径,而/oss的前缀会在真正转发的时候被去掉 也就是真正请求的完整路径是:GateWay的ip+端口号/上下文路径+资源路径
        - id: service-b # 路由ID,唯一即可
          uri: lb://service-b # 转发到的后端服务的服务名,需要与Nacos中注册的服务名一致
          predicates:
            - Path=/service-b/** # 断言,表示请求路径匹配/oss/**的请求将会被转发到后端服务
          filters:
            - StripPrefix=1 # 表示在将请求转发到后端服务之前,去掉路径
sun-rays:
  log4j2:
    home: /Users/sunxiansheng/IdeaProjects/sunrays-framework/sunrays-demo/sunrays-common-cloud-base-starter/gateway/logs # 日志根目录(默认./logs)
    module: sunrays-demo/sunrays-common-cloud-base-starter/gateway # 模块根目录从仓库根目录开始(默认defaultModule)
server:
  port: 8081
3.service-a
1.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud-base-starter</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>service-a</artifactId>

    <dependencies>
        <!-- web -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-web-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>
</project>
2.ServiceAController.java
package com.sunxiansheng.serviceA.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description: ServiceAController
 *
 * @Author sun
 * @Create 2025/1/8 12:57
 * @Version 1.0
 */
@RestController
public class ServiceAController {

    @RequestMapping("/serviceA")
    public String serviceA() {
        return "serviceA";
    }
}
4.service-b
1.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud-base-starter</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>service-b</artifactId>

    <dependencies>
        <!-- web -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-web-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>
</project>
2.ServiceBController.java
package com.sunxiansheng.serviceB.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Description: ServiceBController
 *
 * @Author sun
 * @Create 2025/1/8 12:58
 * @Version 1.0
 */
@RestController
public class ServiceBController {

    @RequestMapping("/serviceB")
    public String serviceB() {
        return "serviceB";
    }
}
5.测试,网关服务发现+前缀+上下文路径+资源路径
http://localhost:8081/service-a/serviceA

CleanShot 2025-01-08 at 13.15.30@2x

http://localhost:8081/service-b/serviceB

CleanShot 2025-01-08 at 13.15.44@2x

4.配置OpenFeign
1.目录结构

CleanShot 2025-01-08 at 13.29.54@2x

2.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>
    <parent>
        <groupId>com.sunxiansheng</groupId>
        <artifactId>sunrays-common-cloud-base-starter</artifactId>
        <version>2.0.0</version>
    </parent>

    <artifactId>service-a</artifactId>

    <dependencies>
        <!-- web -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>common-web-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
        <!-- openfeign -->
        <dependency>
            <groupId>com.sunxiansheng</groupId>
            <artifactId>sunrays-common-cloud-openfeign-starter</artifactId>
            <version>2.0.0</version>
        </dependency>
    </dependencies>
</project>
3.ServiceBRpc.java 暴露rpc接口
package com.sunxiansheng.serviceA.rpc;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * Description: ServiceBRpc
 *
 * @Author sun
 * @Create 2025/1/8 13:18
 * @Version 1.0
 */
@FeignClient(name = "service-b") // 指定要rpc的服务名
public interface ServiceBRpc {

    /**
     * 要请求的方法签名
     *
     * @return
     */
    @RequestMapping("/serviceB")
    String serviceB();
}
4.ServiceAController.java 注入rpc接口,一旦调用就会被代理请求
package com.sunxiansheng.serviceA.controller;

import com.google.gson.Gson;
import com.sunxiansheng.serviceA.rpc.ServiceBRpc;
import com.sunxiansheng.tool.response.ResultWrapper;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * Description: ServiceAController
 *
 * @Author sun
 * @Create 2025/1/8 12:57
 * @Version 1.0
 */
@RestController
public class ServiceAController {

    @RequestMapping("/serviceA")
    public String serviceA() {
        return "serviceA";
    }

    /**
     * 注入rpc接口,一旦调用就会被代理请求
     */
    @Resource
    private ServiceBRpc serviceBRpc;

    @RequestMapping("/rpcToServiceB")
    public String rpcToServiceB() {
        // 获取到的是json
        String json = serviceBRpc.serviceB();
        // 进行手动的json数据转换
        Gson gson = new Gson();
        ResultWrapper resultWrapper = gson.fromJson(json, ResultWrapper.class);
        return (String) resultWrapper.getData();
    }
}
5.ServiceAApplication.java 启动类使用 @EnableFeignClients注解
package com.sunxiansheng.serviceA;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * Description: ServiceA 启动类
 *
 * @Author sun
 * @Create 2025/1/8 12:42
 * @Version 1.0
 */
@SpringBootApplication
@EnableFeignClients
public class ServiceAApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceAApplication.class, args);
    }
}
6.测试

CleanShot 2025-01-08 at 13.36.06@2x

;