参考:https://www.cnblogs.com/liconglong/p/15408858.html#_label2
9090和9091都起名为business配置到nacos上
如图建立微服务项目!!
pom meaven参考:
https://blog.csdn.net/qq_43470725/article/details/123101494
"1.0" encoding="UTF-8"?>
"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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0</modelVersion>
org.springframework.boot</groupId>
spring-boot-starter-parent</artifactId>
2.3.5.RELEASE</version>
<!-- /> <!– lookup parent from repository –>-->
</parent>
com.example</groupId>
demo</artifactId>
0.0.1-SNAPSHOT</version>
cloud</name>
Demo project for Spring Boot</description>
pom</packaging>
.version>1.8</java.version>
-boot.version>2.3.5.RELEASE</spring-boot.version>
.version>8.0.22</mysql.version>
.version>2.1.3</mybatis.version>
-plus.version>3.3.2</mybatis-plus.version>
.version>1.18.16</lombok.version>
-kafka.version>2.5.7.RELEASE</spring-kafka.version>
-amqp-client.version>5.9.0</rabbit-amqp-client.version>
</properties>
com.example</groupId>
dtestcommon</artifactId>
0.0.1-SNAPSHOT</version>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-web</artifactId>
${spring-boot.version}</version>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-test</artifactId>
${spring-boot.version}</version>
test</scope>
</dependency>
mysql</groupId>
mysql-connector-java</artifactId>
${mysql.version}</version>
runtime</scope>
</dependency>
org.mybatis.spring.boot</groupId>
mybatis-spring-boot-starter</artifactId>
2.1.3</version>
</dependency>
org.projectlombok</groupId>
lombok</artifactId>
${lombok.version}</version>
true</optional>
</dependency>
org.springframework.integration</groupId>
spring-integration-mqtt</artifactId>
5.4.6</version>
</dependency>
io.netty</groupId>
netty-all</artifactId>
4.1.42.Final</version>
</dependency>
cn.hutool</groupId>
hutool-all</artifactId>
5.2.3</version>
</dependency>
<!---->
com.gexin.platform</groupId>
gexin-rp-fastjson</artifactId>
1.0.0.7</version>
</dependency>
com.gexin.platform</groupId>
gexin-rp-sdk-base</artifactId>
4.0.0.38</version>
</dependency>
com.gexin.platform</groupId>
gexin-rp-sdk-http</artifactId>
4.1.2.0</version>
</dependency>
com.gexin.platform</groupId>
gexin-rp-sdk-template</artifactId>
4.0.0.30</version>
</dependency>
com.google.protobuf</groupId>
protobuf-java</artifactId>
2.5.0</version>
</dependency>
<!---->
com.fasterxml.jackson.core</groupId>
jackson-core</artifactId>
2.12.3</version>
</dependency>
com.alibaba.cloud</groupId>
spring-cloud-starter-alibaba-nacos-discovery</artifactId>
2.2.4.RELEASE</version>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-data-redis</artifactId>
${spring-boot.version}</version>
</dependency>
org.apache.ibatis</groupId>
ibatis-core</artifactId>
3.0</version>
</dependency>
net.sf.json-lib</groupId>
json-lib</artifactId>
2.4</version>
jdk15</classifier>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-thymeleaf</artifactId>
${spring-boot.version}</version>
</dependency>
org.springframework.cloud</groupId>
spring-cloud-starter-openfeign</artifactId>
2.2.3.RELEASE</version>
</dependency>
<!--阿里云-->
com.aliyun.oss</groupId>
aliyun-sdk-oss</artifactId>
3.10.2</version>
</dependency>
<!-- servlet依赖 -->
javax.servlet</groupId>
javax.servlet-api</artifactId>
</dependency>
javax.servlet</groupId>
jstl</artifactId>
</dependency>
<!-- tomcat的支持-->
org.apache.tomcat.embed</groupId>
tomcat-embed-jasper</artifactId>
provided</scope>
</dependency>
<!--mongodb依赖-->
org.springframework.boot</groupId>
spring-boot-starter-data-mongodb</artifactId>
${spring-boot.version}</version>
</dependency>
<!--引入kafak和spring整合的jar-->
org.springframework.kafka</groupId>
spring-kafka</artifactId>
${spring-kafka.version}</version>
</dependency>
<!-- rabbitmq-->
com.rabbitmq</groupId>
amqp-client</artifactId>
${rabbit-amqp-client.version}</version>
</dependency>
<!-- cloudStream rabbit-->
org.springframework.cloud</groupId>
spring-cloud-starter-stream-rabbit</artifactId>
3.0.8.RELEASE</version>
</dependency>
<!-- cloudStream kafka-->
org.springframework.cloud</groupId>
spring-cloud-starter-stream-kafka</artifactId>
3.0.12.RELEASE</version>
</dependency>
org.apache.commons</groupId>
commons-lang3</artifactId>
3.8</version>
</dependency>
<!-- elasticsearch-->
org.springframework.boot</groupId>
spring-boot-starter-data-elasticsearch</artifactId>
2.3.12.RELEASE</version>
</dependency>
<!-- spring ConfigurationProperties注解包 -->
org.springframework.boot</groupId>
spring-boot-configuration-processor</artifactId>
true</optional>
</dependency>
<!-- 用于矩阵运算 -->
org.ujmp</groupId>
ujmp-core</artifactId>
0.3.0</version>
</dependency>
<!-- 用于显示散点图-->
org.jfree</groupId>
jfreechart</artifactId>
1.5.3</version>
</dependency>
<!--xls(03)对应jia包-->
org.apache.poi</groupId>
poi</artifactId>
4.1.2</version>
</dependency>
<!--xlsx(07)对应jia包-->
org.apache.poi</groupId>
poi-ooxml</artifactId>
4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel -->
com.alibaba</groupId>
easyexcel</artifactId>
2.1.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
org.apache.dubbo</groupId>
dubbo-spring-boot-starter</artifactId>
2.7.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
io.springfox</groupId>
springfox-swagger2</artifactId>
2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
io.springfox</groupId>
springfox-swagger-ui</artifactId>
2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
log4j</groupId>
log4j</artifactId>
1.2.17</version>
</dependency>
<!-- Base64编码需要 -->
org.apache.directory.studio</groupId>
org.apache.commons.codec</artifactId>
1.8</version>
</dependency>
<!-- springdata-->
org.springframework.boot</groupId>
spring-boot-starter-data-jpa</artifactId>
2.6.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
org.redisson</groupId>
redisson</artifactId>
3.16.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
org.redisson</groupId>
redisson-spring-boot-starter</artifactId>
3.16.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel -->
com.alibaba.cloud</groupId>
spring-cloud-starter-alibaba-sentinel</artifactId>
2.2.1.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
org.springframework.boot</groupId>
spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
pom:
"1.0" encoding="UTF-8"?>
"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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0</modelVersion>
com.example</groupId>
demo</artifactId>
0.0.1-SNAPSHOT</version>
<!-- /> <!– lookup parent from repository –>-->
</parent>
com.example</groupId>
business9090</artifactId>
0.0.1-SNAPSHOT</version>
business9090</name>
Demo project for Spring Boot</description>
<!-- -->
<!-- .version>1.8</java.version>-->
<!-- </properties>-->
org.springframework.boot</groupId>
spring-boot-starter-web</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-test</artifactId>
test</scope>
</dependency>
<!-- -->
<!-- mysql</groupId>-->
<!-- mysql-connector-java</artifactId>-->
<!-- runtime</scope>-->
<!-- </dependency>-->
<!-- -->
<!-- org.mybatis.spring.boot</groupId>-->
<!-- mybatis-spring-boot-starter</artifactId>-->
<!-- </dependency>-->
org.projectlombok</groupId>
lombok</artifactId>
true</optional>
</dependency>
cn.hutool</groupId>
hutool-all</artifactId>
</dependency>
com.alibaba.cloud</groupId>
spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-data-redis</artifactId>
</dependency>
org.springframework.cloud</groupId>
spring-cloud-starter-openfeign</artifactId>
</dependency>
org.redisson</groupId>
redisson</artifactId>
</dependency>
org.redisson</groupId>
redisson-spring-boot-starter</artifactId>
</dependency>
</dependencies>
org.springframework.boot</groupId>
spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml配置:
server:
port: 9090
spring:
application:
name: business
# datasource:
# # url: jdbc:mysql://rm-2vc7l62g4u9rt2l82vo.mysql.cn-chengdu.rds.aliyuncs.com:3306/materialbasecloud?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
# # username: root
# # password: jjqhc123456
# url: jdbc:mysql://49.235.125.47:3306/live?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
# username: root
# password: 123456
# driver-class-name: com.mysql.cj.jdbc.Driver
# hikari:
# max-lifetime: 180000
# minimum-idle: 20
# #设置最大线程数量:
# maximum-pool-size: 30
# idle-timeout: 120000
# # 加了之后容易超时
# # connection-test-query: SELECT 1
#redis
redis:
# redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突,通过rdm查看时,在db3的下面
database: 1
# redis服务器地址(默认为loaclhost)
host: 49.235.125.47
# redis端口(默认为6379)
port: 6379
# redis访问密码(默认为空)
password: 123456
# redis连接超时时间(单位毫秒)
timeout: 10000
# redis连接池配置
jedis:
pool:
# 最大可用连接数(默认为8,负数表示无限)
max-active: 8
# 最大空闲连接数(默认为8,负数表示无限)
max-idle: 8
# 最小空闲连接数(默认为0,该值只有为正数才有用)
min-idle: 0
# 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
max-wait: -1
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
controller:
package com.example.business9090.controller;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/cloud")
@Slf4j
public class CloudController {
@Autowired
private RedissonClient redisson;
@Autowired
private RedisTemplate redisTemplate;
@PostMapping("/test")
public String cloudTest(){
String lockKey = "product_001";
String clientId = UUID.randomUUID().toString();
// ridisson分布式锁 获取锁对象
RLock rLock = redisson.getLock(lockKey);
try{
// 不具备原则性,宕机时会出现bug
// Boolean resulet = redisTemplate.opsForValue().setIfAbsent(lockKey,"chunfeng");
// redisTemplate.expire(lockKey,10, TimeUnit.SECONDS);
// Boolean resulet = redisTemplate.opsForValue().setIfAbsent(lockKey,clientId,30,TimeUnit.SECONDS);
// if(!resulet){
// return "error code";
// }
// 加分布式锁
rLock.lock();
System.out.println("9090 -------访问");
}catch (Exception e){
log.error(e.getMessage());
}finally {
// 释放锁
rLock.unlock();
// if(clientId.equals(redisTemplate.opsForValue().get(lockKey))){
// redisTemplate.delete(lockKey);
// }
}
return "9090";
}
}
pom:
"1.0" encoding="UTF-8"?>
"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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0</modelVersion>
com.example</groupId>
demo</artifactId>
0.0.1-SNAPSHOT</version>
/> <!-- lookup parent from repository -->
</parent>
com.example</groupId>
business9091</artifactId>
0.0.1-SNAPSHOT</version>
business9091</name>
Demo project for Spring Boot</description>
.version>1.8</java.version>
</properties>
org.springframework.boot</groupId>
spring-boot-starter-web</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-test</artifactId>
test</scope>
</dependency>
<!-- -->
<!-- mysql</groupId>-->
<!-- mysql-connector-java</artifactId>-->
<!-- runtime</scope>-->
<!-- </dependency>-->
<!-- -->
<!-- org.mybatis.spring.boot</groupId>-->
<!-- mybatis-spring-boot-starter</artifactId>-->
<!-- 2.1.3</version>-->
<!-- </dependency>-->
org.projectlombok</groupId>
lombok</artifactId>
true</optional>
</dependency>
cn.hutool</groupId>
hutool-all</artifactId>
</dependency>
com.alibaba.cloud</groupId>
spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-data-redis</artifactId>
</dependency>
org.springframework.cloud</groupId>
spring-cloud-starter-openfeign</artifactId>
</dependency>
org.redisson</groupId>
redisson</artifactId>
</dependency>
org.redisson</groupId>
redisson-spring-boot-starter</artifactId>
</dependency>
</dependencies>
org.springframework.boot</groupId>
spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml:
server:
port: 9091
spring:
application:
name: business
# datasource:
# # url: jdbc:mysql://rm-2vc7l62g4u9rt2l82vo.mysql.cn-chengdu.rds.aliyuncs.com:3306/materialbasecloud?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
# # username: root
# # password: jjqhc123456
# url: jdbc:mysql://49.235.125.47:3306/live?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
# username: root
# password: 123456
# driver-class-name: com.mysql.cj.jdbc.Driver
# hikari:
# max-lifetime: 180000
# minimum-idle: 20
# #设置最大线程数量:
# maximum-pool-size: 30
# idle-timeout: 120000
# # 加了之后容易超时
# # connection-test-query: SELECT 1
#redis
redis:
# redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突,通过rdm查看时,在db3的下面
database: 1
# redis服务器地址(默认为loaclhost)
host: 49.235.125.47
# redis端口(默认为6379)
port: 6379
# redis访问密码(默认为空)
password: 123456
# redis连接超时时间(单位毫秒)
timeout: 10000
# redis连接池配置
jedis:
pool:
# 最大可用连接数(默认为8,负数表示无限)
max-active: 8
# 最大空闲连接数(默认为8,负数表示无限)
max-idle: 8
# 最小空闲连接数(默认为0,该值只有为正数才有用)
min-idle: 0
# 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
max-wait: -1
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
controller:
package com.example.business9092.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/cloud")
@Slf4j
public class CloudController {
@PostMapping("/test")
public String cloudTest(){
System.out.println("9091 -------访问");
return "9091";
}
}
建立openfigen项目9092:
"1.0" encoding="UTF-8"?>
"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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0</modelVersion>
com.example</groupId>
demo</artifactId>
0.0.1-SNAPSHOT</version>
/> <!-- lookup parent from repository -->
</parent>
com.example</groupId>
business9092fengin</artifactId>
0.0.1-SNAPSHOT</version>
business9092fengin</name>
Demo project for Spring Boot</description>
.version>1.8</java.version>
</properties>
com.example</groupId>
dtestcommon</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-web</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-test</artifactId>
test</scope>
</dependency>
<!-- -->
<!-- mysql</groupId>-->
<!-- mysql-connector-java</artifactId>-->
<!-- runtime</scope>-->
<!-- </dependency>-->
<!-- -->
<!-- org.mybatis.spring.boot</groupId>-->
<!-- mybatis-spring-boot-starter</artifactId>-->
<!-- 2.1.3</version>-->
<!-- </dependency>-->
org.projectlombok</groupId>
lombok</artifactId>
true</optional>
</dependency>
cn.hutool</groupId>
hutool-all</artifactId>
</dependency>
com.alibaba.cloud</groupId>
spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
org.springframework.boot</groupId>
spring-boot-starter-data-redis</artifactId>
</dependency>
org.springframework.cloud</groupId>
spring-cloud-starter-openfeign</artifactId>
</dependency>
org.redisson</groupId>
redisson</artifactId>
</dependency>
org.redisson</groupId>
redisson-spring-boot-starter</artifactId>
</dependency>
</dependencies>
org.springframework.boot</groupId>
spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
yml:
server:
port: 9092
spring:
application:
name: business-9092
datasource:
# url: jdbc:mysql://rm-2vc7l62g4u9rt2l82vo.mysql.cn-chengdu.rds.aliyuncs.com:3306/materialbasecloud?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
# username: root
# password: jjqhc123456
url: jdbc:mysql://49.235.125.47:3306/live?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
max-lifetime: 180000
minimum-idle: 20
#设置最大线程数量:
maximum-pool-size: 30
idle-timeout: 120000
# 加了之后容易超时
# connection-test-query: SELECT 1
#redis
# redis:
# # redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突,通过rdm查看时,在db3的下面
# database: 1
# # redis服务器地址(默认为loaclhost)
# host: 49.235.125.47
# # redis端口(默认为6379)
# port: 6379
# # redis访问密码(默认为空)
# password: 123456
# # redis连接超时时间(单位毫秒)
# timeout: 10000
# # redis连接池配置
# jedis:
# pool:
# # 最大可用连接数(默认为8,负数表示无限)
# max-active: 8
# # 最大空闲连接数(默认为8,负数表示无限)
# max-idle: 8
# # 最小空闲连接数(默认为0,该值只有为正数才有用)
# min-idle: 0
# # 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
# max-wait: -1
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
建立TestFeignClientInterface接口:
package com.example.business9092fengin.cloud.interfaces;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
public interface TestFeignClientInterface {
@PostMapping("/cloud/test")
String cloudTest();
}
建立TestFeignClient接口继承TestFeignClientInterface接口,并加上FeignClient被feign识别:
package com.example.business9092fengin.cloud.client;
import com.example.business9092fengin.cloud.config.FeignConfiguration;
import com.example.business9092fengin.cloud.interfaces.TestFeignClientInterface;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(value = "business",configuration = FeignConfiguration.class)
public interface TestFeignClient extends TestFeignClientInterface {
}
自定义解析类的配置been:
package com.example.business9092fengin.cloud.config;
import com.example.dtestcommon.config.feign.decoder.FeignResDecoder;
import com.example.dtestcommon.config.feign.decoder.token.FeignTokenTransfer;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfiguration {
@Bean
public Decoder feignDecoder() {
return new FeignResDecoder();
}
@Bean
public RequestInterceptor requestInterceptor(){
return new FeignTokenTransfer();
}
}
自定义的解析类: FeignResDecoder
package com.example.dtestcommon.config.feign.decoder;
import com.example.dtestcommon.utils.JsonUtil;
import com.example.dtestcommon.vo.Res;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
@Slf4j
public class FeignResDecoder implements Decoder {
private static final ObjectMapper objectMapper = new ObjectMapper();
static {
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 允许出现特殊字符和转义符
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
// 允许出现单引号
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
}
@Override
public Object decode(Response response, Type type) throws IOException, FeignException {
if (response.body() == null) {
throw new DecodeException(response.status(), "没有返回有效的数据", response.request());
}
// 如果是String类型
if(String.class.equals(type)){
return Util.toString(response.body().asReader());
}
String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));
//第一种情况,如果为Response
if (type instanceof com.example.dtestcommon.vo.Response || Map.class.equals(type)){
return JsonUtil.json2obj(bodyStr,type);
}
//第二种情况,如果有类型,如Res,或者List
if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) type).getRawType();
//如果为如Res
if (Res.class.equals(rawType)) {
return JsonUtil.json2obj(bodyStr, type);
//或者List
}
Res res = JsonUtil.json2obj(bodyStr, Res.class);
return JsonUtil.json2obj(objectMapper.writeValueAsString(res.getData()), type);
} else {
//另一种情况
//如下可以,但是不完美,Result类可能是Res类,也可能是Response
Res res = JsonUtil.json2obj(bodyStr, Res.class);
return JsonUtil.json2obj(objectMapper.writeValueAsString(res.getData()), type);
}
}
}
添加拦截器:FeignTokenTransfer
package com.example.dtestcommon.config.feign.decoder.token;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
public class FeignTokenTransfer implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes==null){
return;
}
HttpServletRequest request = attributes.getRequest();
//添加token
requestTemplate.header("token", request.getHeader("token"));
}
}
启动类添加扫描,将配置feign的类扫描到spring 中:
package com.example.business9092fengin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients({"com.example.business9092fengin.cloud.client"})
@SpringBootApplication
public class Business9092fenginApplication {
public static void main(String[] args) {
SpringApplication.run(Business9092fenginApplication.class, args);
}
}
测试:启动9090、9091、9092
9090和9091都起名为business配置到nacos上
访问:
127.0.0.1:9092/feign/test
参考:https://www.cnblogs.com/liconglong/p/15408858.html#_label2
1、可以配置yml
2、在FeignConfiguration中配置策略规则,选择已有的:
默认时轮询选择
RandomRule():随机选择
package com.example.business9092fengin.cloud.config;
import com.example.dtestcommon.config.feign.decoder.FeignResDecoder;
import com.example.dtestcommon.config.feign.decoder.token.FeignTokenTransfer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FeignConfiguration {
@Bean
public Decoder feignDecoder() {
return new FeignResDecoder();
}
@Bean
public RequestInterceptor requestInterceptor(){
return new FeignTokenTransfer();
}
@Bean
public IRule loadBalancedRule(){
return new RandomRule();
}
}
创建负载均衡规则类:
package com.example.business9092fengin.cloud.rule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
public class CustomRule implements IRule {
private ILoadBalancer lb;
// 用于设置自己要排除掉的端口号!!!!!
public List<Integer> excludePorts;
// 无参构造
public CustomRule() {
}
// 有参构造
public CustomRule(List<Integer> excludePorts) {
this.excludePorts = excludePorts;
}
@Override
public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
this.lb = iLoadBalancer;
}
@Override
public ILoadBalancer getLoadBalancer() {
return lb;
}
/**
* 目标:自定义负载均衡策略:从所有可用的provider中排除掉指定端口号的provider,
* 剩余provider进行随机选择
* 实现步骤:
* 1.获取到所有Server
* 2.从所有Server中排除掉指定端口的Server后,剩余的Server
* 3.从剩余Server中随机选择一个Server
*/
@Override
public Server choose(Object o) {
// 1.获取到所有Server
List<Server> servers = lb.getReachableServers();
// 2.从所有Server中排除掉指定端口的Server后,剩余的Server
List<Server> availableServers = this.getAvailableServers(servers);
// 3.从剩余Server中随机选择一个Server
Server server = this.getAvailableRandomServers(availableServers);
return server;
}
private List<Server> getAvailableServers(List<Server> servers) {
// 若没有指定要排除的port,则返回所有Server
if(excludePorts == null || excludePorts.size() == 0) {
return servers;
}
List<Server> aservers = servers.stream()
// filter()
// noneMatch() 只有当流中所有元素都没有匹配上时,才返回true,只要有一个匹配上了,则返回false
.filter(server -> excludePorts.stream().noneMatch(port -> server.getPort() == port))
.collect(Collectors.toList());
return aservers;
}
// 随机选择服务
private Server getAvailableRandomServers(List<Server> availableServers) {
// 获取一个[0,availableServers.size())的随机数
int index = new Random().nextInt(availableServers.size());
return availableServers.get(index);
}
}
将其配置到FeignConfiguration类中,注入进spring中
package com.example.business9092fengin.cloud.config;
import com.example.business9092fengin.cloud.rule.CustomRule;
import com.example.dtestcommon.config.feign.decoder.FeignResDecoder;
import com.example.dtestcommon.config.feign.decoder.token.FeignTokenTransfer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import feign.RequestInterceptor;
import feign.codec.Decoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class FeignConfiguration {
@Bean
public Decoder feignDecoder() {
return new FeignResDecoder();
}
@Bean
public RequestInterceptor requestInterceptor(){
return new FeignTokenTransfer();
}
// @Bean
// public IRule loadBalancedRule(){
// return new RandomRule();
// }
@Bean
public IRule loadBalancedRule(){
List<Integer> list = new ArrayList<>();
list.add(9090);//排除访问端口
return new CustomRule(list);
}
}
com.alibaba.cloud</groupId>
spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
server:
port: 9092
spring:
application:
name: business-9092
# datasource:
# # url: jdbc:mysql://rm-2vc7l62g4u9rt2l82vo.mysql.cn-chengdu.rds.aliyuncs.com:3306/materialbasecloud?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
# # username: root
# # password: jjqhc123456
# url: jdbc:mysql://49.235.125.47:3306/live?characterEncoding=utf8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
# username: root
# password: 123456
# driver-class-name: com.mysql.cj.jdbc.Driver
# hikari:
# max-lifetime: 180000
# minimum-idle: 20
# #设置最大线程数量:
# maximum-pool-size: 30
# idle-timeout: 120000
# # 加了之后容易超时
# # connection-test-query: SELECT 1
#redis
redis:
# redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突,通过rdm查看时,在db3的下面
database: 1
# redis服务器地址(默认为loaclhost)
host: 49.235.125.47
# redis端口(默认为6379)
port: 6379
# redis访问密码(默认为空)
password: 123456
# redis连接超时时间(单位毫秒)
timeout: 10000
# redis连接池配置
jedis:
pool:
# 最大可用连接数(默认为8,负数表示无限)
max-active: 8
# 最大空闲连接数(默认为8,负数表示无限)
max-idle: 8
# 最小空闲连接数(默认为0,该值只有为正数才有用)
min-idle: 0
# 从连接池中获取连接最大等待时间(默认为-1,单位为毫秒,负数表示无限)
max-wait: -1
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel:
transport:
dashboard: 127.0.0.1:8080
# 为应用开启额外的端口,上报监控信息
# 默认为8719端口,加入被占用将会自动从8719开始+1扫描,直至找到未被占用的端口地址
port: 8719
datasource: #配置流控规则持久化
ds1:
nacos:
server-addr: localhost:8848
dataId: cloudalibaba-sentinel-service
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
## 监控相关
anagement:
endpoints:
web:
exposure:
include: '*'
#开启 sentinel 对 feign 的支持
feign:
sentinel:
enabled: true
配置feign的熔断降级!!
package com.example.business9092fengin.cloud.interfaces;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
public interface TestFeignClientInterface {
@PostMapping("/cloud/test")
String cloudTest();
}
package com.example.business9092fengin.cloud.client;
import com.example.business9092fengin.cloud.config.FeignConfiguration;
import com.example.business9092fengin.cloud.interfaces.TestFeignClientInterface;
import com.example.business9092fengin.cloud.interfaces.impl.TestFeignClientIFallbackImpl;
import org.springframework.cloud.openfeign.FeignClient;
@FeignClient(value = "business",configuration = FeignConfiguration.class,fallback = TestFeignClientIFallbackImpl.class)
public interface TestFeignClient extends TestFeignClientInterface {
}
package com.example.business9092fengin.cloud.interfaces.impl;
import com.example.business9092fengin.cloud.client.TestFeignClient;
import com.example.business9092fengin.cloud.interfaces.TestFeignClientInterface;
import org.springframework.stereotype.Component;
@Component
public class TestFeignClientIFallbackImpl implements TestFeignClient {
@Override
public String cloudTest() {
String str = "调用失败,服务被降级";
return str;
}
}
controller:
这里需要注意要使用:@Qualifier指定时哪一个类,应为继承testFeignClient接口的类有两个!!
因为有@Component注入的bean的类和主启动扫描注入的bean
package com.example.business9092fengin.controller;
import com.example.business9092fengin.cloud.client.TestFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/feign")
public class TestFeignController {
@Qualifier("com.example.business9092fengin.cloud.client.TestFeignClient")
@Autowired
TestFeignClient testFeignClient;
@PostMapping("/test")
public String test(){
String str = testFeignClient.cloudTest();
System.out.println("访问--"+str);
return str;
}
}