mirror of https://github.com/jeecgboot/jeecg-boot
JeecgBoot3.2.0 版本发布 [优化微服务模块]
parent
7f87042e59
commit
c14a793906
|
@ -2,6 +2,7 @@ package org.jeecg.config;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
|
@ -19,11 +20,9 @@ import static org.springframework.web.reactive.function.server.ServerResponse.ok
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@RefreshScope
|
||||||
public class GatewayRoutersConfiguration {
|
public class GatewayRoutersConfiguration {
|
||||||
/**
|
|
||||||
* 路由配置方式:database,yml,nacos
|
|
||||||
*/
|
|
||||||
public static String DATA_TYPE;
|
|
||||||
public static final long DEFAULT_TIMEOUT = 30000;
|
public static final long DEFAULT_TIMEOUT = 30000;
|
||||||
public static String SERVER_ADDR;
|
public static String SERVER_ADDR;
|
||||||
public static String NAMESPACE;
|
public static String NAMESPACE;
|
||||||
|
@ -52,10 +51,6 @@ public class GatewayRoutersConfiguration {
|
||||||
ROUTE_GROUP = routeGroup;
|
ROUTE_GROUP = routeGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Value("${jeecg.route.config.data-type:#{null}}")
|
|
||||||
public void setDataType(String dataType) {
|
|
||||||
DATA_TYPE = dataType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value("${spring.cloud.nacos.config.username}")
|
@Value("${spring.cloud.nacos.config.username}")
|
||||||
public void setUsername(String username) {
|
public void setUsername(String username) {
|
||||||
|
|
|
@ -2,6 +2,8 @@ package org.jeecg.config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nocos配置方式枚举
|
* nocos配置方式枚举
|
||||||
|
* @author zyf
|
||||||
|
* @date: 2022/4/21 10:55
|
||||||
*/
|
*/
|
||||||
public enum RouterDataType {
|
public enum RouterDataType {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class GatewaySentinelExceptionConfig {
|
||||||
} else {
|
} else {
|
||||||
msg = "未知限流降级";
|
msg = "未知限流降级";
|
||||||
}
|
}
|
||||||
HashMap<String, String> map = new HashMap();
|
HashMap<String, String> map = new HashMap(5);
|
||||||
map.put("code", HttpStatus.TOO_MANY_REQUESTS.toString());
|
map.put("code", HttpStatus.TOO_MANY_REQUESTS.toString());
|
||||||
map.put("message", msg);
|
map.put("message", msg);
|
||||||
//自定义异常处理
|
//自定义异常处理
|
||||||
|
|
|
@ -30,22 +30,17 @@ public class GlobalAccessTokenFilter implements GlobalFilter, Ordered {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||||
String url = exchange.getRequest().getURI().getPath();
|
|
||||||
// log.info(" access url : "+ url);
|
|
||||||
|
|
||||||
String scheme = exchange.getRequest().getURI().getScheme();
|
String scheme = exchange.getRequest().getURI().getScheme();
|
||||||
String host = exchange.getRequest().getURI().getHost();
|
String host = exchange.getRequest().getURI().getHost();
|
||||||
int port = exchange.getRequest().getURI().getPort();
|
int port = exchange.getRequest().getURI().getPort();
|
||||||
String basePath = scheme + "://" + host + ":" + port;
|
String basePath = scheme + "://" + host + ":" + port;
|
||||||
// log.info(" base path : "+ basePath);
|
|
||||||
|
|
||||||
// 1. 重写StripPrefix(获取真实的URL)
|
// 1. 重写StripPrefix(获取真实的URL)
|
||||||
addOriginalRequestUrl(exchange, exchange.getRequest().getURI());
|
addOriginalRequestUrl(exchange, exchange.getRequest().getURI());
|
||||||
String rawPath = exchange.getRequest().getURI().getRawPath();
|
String rawPath = exchange.getRequest().getURI().getRawPath();
|
||||||
String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/")).skip(1L).collect(Collectors.joining("/"));
|
String newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/")).skip(1L).collect(Collectors.joining("/"));
|
||||||
ServerHttpRequest newRequest = exchange.getRequest().mutate().path(newPath).build();
|
ServerHttpRequest newRequest = exchange.getRequest().mutate().path(newPath).build();
|
||||||
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
|
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
|
||||||
|
|
||||||
//2.将现在的request,添加当前身份
|
//2.将现在的request,添加当前身份
|
||||||
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization-UserName", "").header(X_GATEWAY_BASE_PATH,basePath).build();
|
ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("Authorization-UserName", "").header(X_GATEWAY_BASE_PATH,basePath).build();
|
||||||
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
|
ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
|
||||||
|
|
|
@ -11,6 +11,8 @@ import javax.annotation.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 路由刷新监听(实现方式:redis监听handler)
|
* 路由刷新监听(实现方式:redis监听handler)
|
||||||
|
* @author zyf
|
||||||
|
* @date: 2022/4/21 10:55
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component(GlobalConstants.LODER_ROUDER_HANDLER)
|
@Component(GlobalConstants.LODER_ROUDER_HANDLER)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.handler.swagger;
|
package org.jeecg.handler.swagger;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.alibaba.nacos.api.naming.NamingFactory;
|
import com.alibaba.nacos.api.naming.NamingFactory;
|
||||||
import com.alibaba.nacos.api.naming.NamingService;
|
import com.alibaba.nacos.api.naming.NamingService;
|
||||||
|
@ -21,6 +22,8 @@ import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 聚合各个服务的swagger接口
|
* 聚合各个服务的swagger接口
|
||||||
|
* @author zyf
|
||||||
|
* @date: 2022/4/21 10:55
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -42,6 +45,11 @@ public class MySwaggerResourceProvider implements SwaggerResourcesProvider {
|
||||||
@Value("${spring.cloud.nacos.discovery.server-addr}")
|
@Value("${spring.cloud.nacos.discovery.server-addr}")
|
||||||
private String serverAddr;
|
private String serverAddr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swagger中需要排除的服务
|
||||||
|
*/
|
||||||
|
private String[] excludeServiceIds=new String[]{"jeecg-cloud-monitor"};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 网关应用名称
|
* 网关应用名称
|
||||||
|
@ -82,8 +90,8 @@ public class MySwaggerResourceProvider implements SwaggerResourcesProvider {
|
||||||
swaggerResource.setUrl(url);
|
swaggerResource.setUrl(url);
|
||||||
swaggerResource.setSwaggerVersion("2.0");
|
swaggerResource.setSwaggerVersion("2.0");
|
||||||
swaggerResource.setName(instance);
|
swaggerResource.setName(instance);
|
||||||
//Swagger排除监控
|
//Swagger排除不展示的服务
|
||||||
if(instance.indexOf("jeecg-cloud-monitor")==-1){
|
if(!ArrayUtil.contains(excludeServiceIds,instance)){
|
||||||
resources.add(swaggerResource);
|
resources.add(swaggerResource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* swagger聚合接口,三个接口都是 doc.html需要访问的接口
|
* swagger聚合接口,三个接口都是 doc.html需要访问的接口
|
||||||
|
* @author zyf
|
||||||
|
* @date: 2022/4/21 10:55
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/swagger-resources")
|
@RequestMapping("/swagger-resources")
|
||||||
|
|
|
@ -21,6 +21,8 @@ import org.jeecg.config.RouterDataType;
|
||||||
import org.jeecg.loader.repository.DynamicRouteService;
|
import org.jeecg.loader.repository.DynamicRouteService;
|
||||||
import org.jeecg.loader.repository.MyInMemoryRouteDefinitionRepository;
|
import org.jeecg.loader.repository.MyInMemoryRouteDefinitionRepository;
|
||||||
import org.jeecg.loader.vo.MyRouteDefinition;
|
import org.jeecg.loader.vo.MyRouteDefinition;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||||
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
|
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
|
||||||
import org.springframework.cloud.gateway.filter.FilterDefinition;
|
import org.springframework.cloud.gateway.filter.FilterDefinition;
|
||||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||||
|
@ -49,6 +51,7 @@ import java.util.concurrent.Executor;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@DependsOn({"gatewayRoutersConfiguration"})
|
@DependsOn({"gatewayRoutersConfiguration"})
|
||||||
|
@RefreshScope
|
||||||
public class DynamicRouteLoader implements ApplicationEventPublisherAware {
|
public class DynamicRouteLoader implements ApplicationEventPublisherAware {
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,6 +60,12 @@ public class DynamicRouteLoader implements ApplicationEventPublisherAware {
|
||||||
private DynamicRouteService dynamicRouteService;
|
private DynamicRouteService dynamicRouteService;
|
||||||
private ConfigService configService;
|
private ConfigService configService;
|
||||||
private RedisUtil redisUtil;
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由配置方式:database(数据库),yml(配置文件),nacos
|
||||||
|
*/
|
||||||
|
@Value("${jeecg.route.config.data-type:database}")
|
||||||
|
public String dataType;
|
||||||
/**
|
/**
|
||||||
* 需要拼接key的路由条件
|
* 需要拼接key的路由条件
|
||||||
*/
|
*/
|
||||||
|
@ -76,7 +85,6 @@ public class DynamicRouteLoader implements ApplicationEventPublisherAware {
|
||||||
|
|
||||||
|
|
||||||
public void init(BaseMap baseMap) {
|
public void init(BaseMap baseMap) {
|
||||||
String dataType = GatewayRoutersConfiguration.DATA_TYPE;
|
|
||||||
log.info("初始化路由,dataType:"+ dataType);
|
log.info("初始化路由,dataType:"+ dataType);
|
||||||
if (RouterDataType.nacos.toString().endsWith(dataType)) {
|
if (RouterDataType.nacos.toString().endsWith(dataType)) {
|
||||||
loadRoutesByNacos();
|
loadRoutesByNacos();
|
||||||
|
@ -92,7 +100,6 @@ public class DynamicRouteLoader implements ApplicationEventPublisherAware {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public Mono<Void> refresh(BaseMap baseMap) {
|
public Mono<Void> refresh(BaseMap baseMap) {
|
||||||
String dataType = GatewayRoutersConfiguration.DATA_TYPE;
|
|
||||||
if (!RouterDataType.yml.toString().endsWith(dataType)) {
|
if (!RouterDataType.yml.toString().endsWith(dataType)) {
|
||||||
this.init(baseMap);
|
this.init(baseMap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,6 @@ public class DynamicRouteService implements ApplicationEventPublisherAware {
|
||||||
public synchronized String update(RouteDefinition definition) {
|
public synchronized String update(RouteDefinition definition) {
|
||||||
try {
|
try {
|
||||||
log.info("gateway update route {}", definition);
|
log.info("gateway update route {}", definition);
|
||||||
//delete(definition.getId());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return "update fail,not find route routeId: " + definition.getId();
|
return "update fail,not find route routeId: " + definition.getId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,11 @@ package org.jeecg.loader.vo;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 路由参数模型
|
||||||
|
* @author zyf
|
||||||
|
* @date: 2022/4/21 10:55
|
||||||
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class GatewayRouteVo {
|
public class GatewayRouteVo {
|
||||||
private String id;
|
private String id;
|
||||||
|
|
|
@ -6,6 +6,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监控服务
|
* 监控服务
|
||||||
|
* @author zyf
|
||||||
|
* @date: 2022/4/21 10:55
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableAdminServer
|
@EnableAdminServer
|
||||||
|
|
|
@ -8,8 +8,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nacos 启动类
|
* Nacos 启动类
|
||||||
* 引用的nacos console 源码运行,简化开发
|
*
|
||||||
* 生产建议从官网下载最新版配置运行
|
|
||||||
* @author zyf
|
* @author zyf
|
||||||
*/
|
*/
|
||||||
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
|
@SpringBootApplication(scanBasePackages = "com.alibaba.nacos")
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.net.UnknownHostException;
|
||||||
/**
|
/**
|
||||||
* 微服务启动类(采用此类启动项目为微服务模式)
|
* 微服务启动类(采用此类启动项目为微服务模式)
|
||||||
* 注意: 需要先在naocs里面创建配置文件,参考文档 http://doc.jeecg.com/2704725
|
* 注意: 需要先在naocs里面创建配置文件,参考文档 http://doc.jeecg.com/2704725
|
||||||
|
* @author zyf
|
||||||
|
* @date: 2022/4/21 10:55
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
|
|
@ -2,6 +2,8 @@ package org.jeecg.modules.test.constant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微服务单元测试常量定义
|
* 微服务单元测试常量定义
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
public interface CloudConstant {
|
public interface CloudConstant {
|
||||||
|
|
||||||
|
|
|
@ -9,17 +9,22 @@ import org.jeecg.modules.test.feign.factory.JeecgTestClientFactory;
|
||||||
import org.springframework.cloud.openfeign.FeignClient;
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.Mapping;
|
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 常规feign接口定义
|
* 常规feign接口定义
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@FeignClient(value = ServiceNameConstants.SERVICE_DEMO, configuration = FeignConfig.class,fallbackFactory = JeecgTestClientFactory.class)
|
@FeignClient(value = ServiceNameConstants.SERVICE_DEMO, configuration = FeignConfig.class,fallbackFactory = JeecgTestClientFactory.class)
|
||||||
@Component
|
@Component
|
||||||
public interface JeecgTestClient {
|
public interface JeecgTestClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* feign测试方法
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
@GetMapping(value = "/test/getMessage")
|
@GetMapping(value = "/test/getMessage")
|
||||||
String getMessage(@RequestParam(value = "name",required = false) String name);
|
String getMessage(@RequestParam(value = "name",required = false) String name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,11 @@ import com.alibaba.csp.sentinel.annotation.SentinelResource;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微服务单元测试
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/sys/test")
|
@RequestMapping("/sys/test")
|
||||||
|
|
|
@ -14,6 +14,8 @@ import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分布式锁测试demo
|
* 分布式锁测试demo
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
|
@ -50,10 +52,11 @@ public class DemoLockTest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试分布式锁【编码方式】
|
* 测试分布式锁【编码方式】
|
||||||
|
* @Scheduled(cron = "0/5 * * * * ?")
|
||||||
*/
|
*/
|
||||||
//@Scheduled(cron = "0/5 * * * * ?")
|
|
||||||
public void execute2() throws InterruptedException {
|
public void execute2() throws InterruptedException {
|
||||||
if (redissonLock.tryLock(CloudConstant.REDISSON_DEMO_LOCK_KEY2, -1, 6000)) {
|
int expireSeconds=6000;
|
||||||
|
if (redissonLock.tryLock(CloudConstant.REDISSON_DEMO_LOCK_KEY2, -1, expireSeconds)) {
|
||||||
log.info("执行任务execute2开始,休眠十秒");
|
log.info("执行任务execute2开始,休眠十秒");
|
||||||
Thread.sleep(10000);
|
Thread.sleep(10000);
|
||||||
log.info("=============业务逻辑2===================");
|
log.info("=============业务逻辑2===================");
|
||||||
|
|
|
@ -20,6 +20,8 @@ import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xxl-job定时任务测试
|
* xxl-job定时任务测试
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -113,7 +115,8 @@ public class DemoJobHandler {
|
||||||
*/
|
*/
|
||||||
@XxlJob("httpJobHandler")
|
@XxlJob("httpJobHandler")
|
||||||
public ReturnT<String> httpJobHandler(String param) throws Exception {
|
public ReturnT<String> httpJobHandler(String param) throws Exception {
|
||||||
|
String[] methodArray=new String[]{"GET","POST"};
|
||||||
|
int okState=200;
|
||||||
// param parse
|
// param parse
|
||||||
if (param == null || param.trim().length() == 0) {
|
if (param == null || param.trim().length() == 0) {
|
||||||
log.info("param[" + param + "] invalid.");
|
log.info("param[" + param + "] invalid.");
|
||||||
|
@ -140,7 +143,7 @@ public class DemoJobHandler {
|
||||||
log.info("url[" + url + "] invalid.");
|
log.info("url[" + url + "] invalid.");
|
||||||
return ReturnT.FAIL;
|
return ReturnT.FAIL;
|
||||||
}
|
}
|
||||||
if (method == null || !Arrays.asList("GET", "POST").contains(method)) {
|
if (method == null || !Arrays.asList(methodArray).contains(method)) {
|
||||||
log.info("method[" + method + "] invalid.");
|
log.info("method[" + method + "] invalid.");
|
||||||
return ReturnT.FAIL;
|
return ReturnT.FAIL;
|
||||||
}
|
}
|
||||||
|
@ -177,7 +180,7 @@ public class DemoJobHandler {
|
||||||
|
|
||||||
// valid StatusCode
|
// valid StatusCode
|
||||||
int statusCode = connection.getResponseCode();
|
int statusCode = connection.getResponseCode();
|
||||||
if (statusCode != 200) {
|
if (statusCode != okState) {
|
||||||
throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
|
throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,10 @@ import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xxl-job定时任务测试
|
* xxl-job定时任务测试
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
|
|
@ -2,6 +2,8 @@ package org.jeecg.modules.test.rabbitmq.constant;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 微服务单元测试常量定义
|
* 微服务单元测试常量定义
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
public interface CloudConstant {
|
public interface CloudConstant {
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ import io.swagger.annotations.ApiOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RabbitMqClient发送消息
|
* RabbitMqClient发送消息
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/sys/test")
|
@RequestMapping("/sys/test")
|
||||||
|
|
|
@ -11,6 +11,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息处理器【发布订阅】
|
* 消息处理器【发布订阅】
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component(CloudConstant.MQ_DEMO_BUS_EVENT)
|
@Component(CloudConstant.MQ_DEMO_BUS_EVENT)
|
||||||
|
|
|
@ -21,6 +21,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||||
*
|
*
|
||||||
* RabbitMq接受者1
|
* RabbitMq接受者1
|
||||||
* (@RabbitListener声明类上,一个类只能监听一个队列)
|
* (@RabbitListener声明类上,一个类只能监听一个队列)
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RabbitListener(queues = CloudConstant.MQ_JEECG_PLACE_ORDER)
|
@RabbitListener(queues = CloudConstant.MQ_JEECG_PLACE_ORDER)
|
||||||
|
|
|
@ -17,6 +17,8 @@ import org.springframework.messaging.handler.annotation.Header;
|
||||||
*
|
*
|
||||||
* RabbitMq接受者2
|
* RabbitMq接受者2
|
||||||
* (@RabbitListener声明类上,一个类只能监听一个队列)
|
* (@RabbitListener声明类上,一个类只能监听一个队列)
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RabbitListener(queues = CloudConstant.MQ_JEECG_PLACE_ORDER)
|
@RabbitListener(queues = CloudConstant.MQ_JEECG_PLACE_ORDER)
|
||||||
|
|
|
@ -16,6 +16,8 @@ import org.springframework.messaging.handler.annotation.Header;
|
||||||
*
|
*
|
||||||
* RabbitMq接受者3【我是处理人3】
|
* RabbitMq接受者3【我是处理人3】
|
||||||
* (@RabbitListener声明类方法上,一个类可以多监听多个队列)
|
* (@RabbitListener声明类方法上,一个类可以多监听多个队列)
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RabbitComponent(value = "helloReceiver3")
|
@RabbitComponent(value = "helloReceiver3")
|
||||||
|
|
|
@ -14,6 +14,11 @@ import com.rabbitmq.client.Channel;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义接收者(可以定义N个接受者,消息会均匀的发送到N个接收者中)
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RabbitListener(queues = CloudConstant.MQ_JEECG_PLACE_ORDER_TIME)
|
@RabbitListener(queues = CloudConstant.MQ_JEECG_PLACE_ORDER_TIME)
|
||||||
@RabbitComponent(value = "helloTimeReceiver")
|
@RabbitComponent(value = "helloTimeReceiver")
|
||||||
|
|
|
@ -10,6 +10,7 @@ import java.math.BigDecimal;
|
||||||
*/
|
*/
|
||||||
public interface SeataAccountService {
|
public interface SeataAccountService {
|
||||||
/**
|
/**
|
||||||
|
* 扣减金额
|
||||||
* @param userId 用户 ID
|
* @param userId 用户 ID
|
||||||
* @param amount 扣减金额
|
* @param amount 扣减金额
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class SeataAccountServiceImpl implements SeataAccountService {
|
||||||
*/
|
*/
|
||||||
@DS("account")
|
@DS("account")
|
||||||
@Override
|
@Override
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
|
||||||
public void reduceBalance(Long userId, BigDecimal amount) {
|
public void reduceBalance(Long userId, BigDecimal amount) {
|
||||||
log.info("=============ACCOUNT START=================");
|
log.info("=============ACCOUNT START=================");
|
||||||
SeataAccount account = accountMapper.selectById(userId);
|
SeataAccount account = accountMapper.selectById(userId);
|
||||||
|
|
|
@ -6,6 +6,11 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分布式事务产品feign客户端
|
||||||
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
|
*/
|
||||||
@FeignClient(value ="seata-product")
|
@FeignClient(value ="seata-product")
|
||||||
public interface ProductClient {
|
public interface ProductClient {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class SeataOrderServiceImpl implements SeataOrderService {
|
||||||
|
|
||||||
@DS("order")
|
@DS("order")
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@GlobalTransactional
|
@GlobalTransactional
|
||||||
public void placeOrder(PlaceOrderRequest request) {
|
public void placeOrder(PlaceOrderRequest request) {
|
||||||
log.info("=============ORDER START=================");
|
log.info("=============ORDER START=================");
|
||||||
|
|
|
@ -32,7 +32,7 @@ public class SeataProductServiceImpl implements SeataProductService {
|
||||||
* 事务传播特性设置为 REQUIRES_NEW 开启新的事务
|
* 事务传播特性设置为 REQUIRES_NEW 开启新的事务
|
||||||
*/
|
*/
|
||||||
@DS("product")
|
@DS("product")
|
||||||
@Transactional(propagation = Propagation.REQUIRES_NEW)
|
@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor = Exception.class)
|
||||||
@Override
|
@Override
|
||||||
public BigDecimal reduceStock(Long productId, Integer count) {
|
public BigDecimal reduceStock(Long productId, Integer count) {
|
||||||
log.info("=============PRODUCT START=================");
|
log.info("=============PRODUCT START=================");
|
||||||
|
|
|
@ -35,7 +35,8 @@ public class JeecgShardingDemoController extends JeecgController<ShardingSysLog,
|
||||||
@PostMapping(value = "/test1")
|
@PostMapping(value = "/test1")
|
||||||
@ApiOperation(value = "单库分表插入", notes = "单库分表")
|
@ApiOperation(value = "单库分表插入", notes = "单库分表")
|
||||||
public Result<?> add() {
|
public Result<?> add() {
|
||||||
for (int i = 0; i < 10; i++) {
|
int size=10;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
ShardingSysLog shardingSysLog = new ShardingSysLog();
|
ShardingSysLog shardingSysLog = new ShardingSysLog();
|
||||||
shardingSysLog.setLogContent("jeecg");
|
shardingSysLog.setLogContent("jeecg");
|
||||||
shardingSysLog.setLogType(i);
|
shardingSysLog.setLogType(i);
|
||||||
|
@ -62,7 +63,9 @@ public class JeecgShardingDemoController extends JeecgController<ShardingSysLog,
|
||||||
@PostMapping(value = "/test2")
|
@PostMapping(value = "/test2")
|
||||||
@ApiOperation(value = "双库分表插入", notes = "双库分表")
|
@ApiOperation(value = "双库分表插入", notes = "双库分表")
|
||||||
public Result<?> test2() {
|
public Result<?> test2() {
|
||||||
for (int i = 20; i <= 30; i++) {
|
int start=20;
|
||||||
|
int size=30;
|
||||||
|
for (int i = start; i <= size; i++) {
|
||||||
ShardingSysLog shardingSysLog = new ShardingSysLog();
|
ShardingSysLog shardingSysLog = new ShardingSysLog();
|
||||||
shardingSysLog.setLogContent("双库分表测试");
|
shardingSysLog.setLogContent("双库分表测试");
|
||||||
shardingSysLog.setLogType(i);
|
shardingSysLog.setLogType(i);
|
||||||
|
|
|
@ -14,9 +14,9 @@ import java.io.Serializable;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
|
||||||
* 系统日志表
|
* 系统日志表
|
||||||
* </p>
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@TableName("sys_log")
|
@TableName("sys_log")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="org.jeecg.modules.demo.sharding.mapper.ShardingSysLogMapper">
|
<mapper namespace="org.jeecg.modules.test.sharding.mapper.ShardingSysLogMapper">
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|
|
@ -8,9 +8,9 @@ import org.jeecg.modules.test.sharding.service.IShardingSysLogService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
|
||||||
* 系统日志表 服务实现类
|
* 系统日志表 服务实现类
|
||||||
* </p>
|
* @author: zyf
|
||||||
|
* @date: 2022/04/21
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@DS("sharding")
|
@DS("sharding")
|
||||||
|
|
Loading…
Reference in New Issue