From fd053ade57317fce55b1b6e6a4036a7d023ebc0b Mon Sep 17 00:00:00 2001 From: zhanghongwei Date: Fri, 11 Mar 2022 10:06:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=EF=BC=91=E3=80=81=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E9=9B=86=E6=88=90RabbitMQ=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=80=9A=E8=BF=87@Primary=E6=B3=A8=E8=A7=A3=E5=88=87?= =?UTF-8?q?=E6=8D=A2=E5=BC=82=E6=AD=A5=E8=B0=83=E7=94=A8=E8=BF=98=E6=98=AF?= =?UTF-8?q?MQ=E8=B0=83=E7=94=A8=E6=97=A5=E5=BF=97=E6=9C=8D=E5=8A=A1=20?= =?UTF-8?q?=EF=BC=92=E3=80=81=E6=96=B0=E5=A2=9EMQ=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E5=92=8C=E4=BD=BF=E7=94=A8markdown=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-common/ruoyi-common-log/README.md | 72 +++++++++++++++++++ ruoyi-common/ruoyi-common-log/pom.xml | 12 ++++ .../ruoyi/common/log/aspect/LogAspect.java | 8 +-- .../log/mq/rabbit/RabbitLogCallback.java | 48 +++++++++++++ .../common/log/mq/rabbit/RabbitLogDirect.java | 58 +++++++++++++++ .../ruoyi/common/log/service/ILogService.java | 16 +++++ .../log/service/impl/AsyncLogService.java | 33 +++++++++ .../log/service/impl/RabbitLogService.java | 68 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 5 +- 9 files changed, 315 insertions(+), 5 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-log/README.md create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogCallback.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogDirect.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/ILogService.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/AsyncLogService.java create mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/RabbitLogService.java diff --git a/ruoyi-common/ruoyi-common-log/README.md b/ruoyi-common/ruoyi-common-log/README.md new file mode 100644 index 00000000..159f2af2 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/README.md @@ -0,0 +1,72 @@ +**

使用MQ的场景和优点

** +#### 解耦 +看这么个场景。A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A 系统负责人几乎崩溃......
+![mq-1](https://gitee.com/shishan100/Java-Interview-Advanced/raw/master/images/mq-1.png)
+在这个场景中,A 系统跟其它各种乱七八糟的系统严重耦合,A 系统产生一条比较关键的数据,很多系统都需要 A 系统将这个数据发送过来。A 系统要时时刻刻考虑 BCDE 四个系统如果挂了该咋办?要不要重发,要不要把消息存起来?头发都白了啊!
+如果使用 MQ,A 系统产生一条数据,发送到 MQ 里面去,哪个系统需要数据自己去 MQ 里面消费。如果新系统需要数据,直接从 MQ 里消费即可;如果某个系统不需要这条数据了,就取消对 MQ 消息的消费即可。这样下来,A 系统压根儿不需要去考虑要给谁发送数据,不需要维护这个代码,也不需要考虑人家是否调用成功、失败超时等情况。
+![mq-2](https://gitee.com/shishan100/Java-Interview-Advanced/raw/master/images/mq-2.png)
+**总结**:通过一个 MQ,Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了。
+ +#### 异步 +再来看一个场景,A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求,等待个 1s,这几乎是不可接受的。
+![mq-3](https://gitee.com/shishan100/Java-Interview-Advanced/raw/master/images/mq-3.png)
+一般互联网类的企业,对于用户直接的操作,一般要求是每个请求都必须在 200 ms 以内完成,对用户几乎是无感知的。
+如果**使用 MQ**,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms,对于用户而言,其实感觉上就是点个按钮,8ms 以后就直接返回了,爽!网站做得真好,真快!
+![mq-4](https://gitee.com/shishan100/Java-Interview-Advanced/raw/master/images/mq-4.png)
+ +#### 削峰 +每天 0:00 到 12:00,A 系统风平浪静,每秒并发请求数量就 50 个。结果每次一到 12:00 ~ 13:00 ,每秒并发请求数量突然会暴增到 5k+ 条。但是系统是直接基于 MySQL 的,大量的请求涌入 MySQL,每秒钟对 MySQL 执行约 5k 条 SQL。
+一般的 MySQL,扛到每秒 2k 个请求就差不多了,如果每秒请求到 5k 的话,可能就直接把 MySQL 给打死了,导致系统崩溃,用户也就没法再使用系统了。
+但是高峰期一过,到了下午的时候,就成了低峰期,可能也就 1w 的用户同时在网站上操作,每秒中的请求数量可能也就 50 个请求,对整个系统几乎没有任何的压力。
+![mq-5](https://gitee.com/shishan100/Java-Interview-Advanced/raw/master/images/mq-5.png)
+如果使用 MQ,每秒 5k 个请求写入 MQ,A 系统每秒钟最多处理 2k 个请求,因为 MySQL 每秒钟最多处理 2k 个。A 系统从 MQ 中慢慢拉取请求,每秒钟就拉取 2k 个请求,不要超过自己每秒能处理的最大请求数量就 ok,这样下来,哪怕是高峰期的时候,A 系统也绝对不会挂掉。而 MQ 每秒钟 5k 个请求进来,就 2k 个请求出去,结果就导致在中午高峰期(1 个小时),可能有几十万甚至几百万的请求积压在 MQ 中。
+![mq-6](https://gitee.com/shishan100/Java-Interview-Advanced/raw/master/images/mq-6.png)
+这个短暂的高峰期积压是 ok 的,因为高峰期过了之后,每秒钟就 50 个请求进 MQ,但是 A 系统依然会按照每秒 2k 个请求的速度在处理。所以说,只要高峰期一过,A 系统就会快速将积压的消息给解决掉。
+ +**

RabbitMQ简介

** +RabbitMQ是一个开源的消息代理的队列服务器,用来通过普通协议在完全不同的应用之间共享数据。
+RabbitMQ是使用Erlang语言来编写的,并且RabbitMQ是基于AMQP协议的。
+Erlang语言在数据交互方面性能优秀,有着和原生Socket一样的延迟,
+这也是RabbitMQ高性能的原因所在。可谓“人如其名”,RabbitMQ像兔子一样迅速。
+ +**

RabbitMQ安装

** +**

RabbitMQ官方下载

** +https://www.rabbitmq.com/download.html +**

Docker下载

** +docker run -d --hostname hostname \ +--name name \ +-p 15672:15672 \ +-p 5672:5672 \ +-e "RABBITMQ_DEFAULT_USER=username" \ +-e "RABBITMQ_DEFAULT_PASS=password" \ +rabbitmq + +**

RabbitMQ常用交换机

** +**

直连型交换机-Direct Exchange

** +一一对应的模式,本次提交的代码即为该模式,用于日志组件的调用 +**

主题交换机-Topic Exchange

** +根据规则一对多的模式,比较负责的项目会使用到 +**

扇型交换机-Fanout Exchange

** +广播的模式,不太注重幂等性的场景可能会使用到 + +**

Nacos中配置yml

** +\# spring配置
+spring:
+ \# 配置rabbitMq 服务器
+  rabbitmq:
+   host: ip
+   port: port
+   username: username
+   password: password
+   \# 确认消息已发送到交换机(Exchange)
+   publisher-confirm-type: correlated
+   \# 确认消息已发送到队列(Queue)
+   publisher-returns: true
+   listener:
+    simple:
+     acknowledge-mode: manual
+ +**

操作日志切换为MQ模式

**
+

step1:将AsyncLogService的@Primary注解删除

+

step2:给RabbitLogService添加@Primary注解

+

step3:启动项目即可

\ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-log/pom.xml b/ruoyi-common/ruoyi-common-log/pom.xml index 5dc1f8e4..59d3b5dc 100644 --- a/ruoyi-common/ruoyi-common-log/pom.xml +++ b/ruoyi-common/ruoyi-common-log/pom.xml @@ -22,6 +22,18 @@ com.ruoyi ruoyi-common-security + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-amqp + \ No newline at end of file diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java index c7237f15..a0f97402 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/aspect/LogAspect.java @@ -4,6 +4,7 @@ import java.util.Collection; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import com.ruoyi.common.log.service.ILogService; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; @@ -21,7 +22,6 @@ import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.ip.IpUtils; import com.ruoyi.common.log.annotation.Log; import com.ruoyi.common.log.enums.BusinessStatus; -import com.ruoyi.common.log.service.AsyncLogService; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.system.api.domain.SysOperLog; @@ -37,7 +37,7 @@ public class LogAspect private static final Logger log = LoggerFactory.getLogger(LogAspect.class); @Autowired - private AsyncLogService asyncLogService; + private ILogService logService; /** * 处理完请求后执行 @@ -92,8 +92,8 @@ public class LogAspect operLog.setRequestMethod(ServletUtils.getRequest().getMethod()); // 处理设置注解上的参数 getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult); - // 保存数据库 - asyncLogService.saveSysLog(operLog); + // 保存日志 + logService.saveSysLog(operLog); } catch (Exception exp) { diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogCallback.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogCallback.java new file mode 100644 index 00000000..d9759cc5 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogCallback.java @@ -0,0 +1,48 @@ +package com.ruoyi.common.log.mq.rabbit; + +import org.springframework.amqp.core.ReturnedMessage; +import org.springframework.amqp.rabbit.connection.ConnectionFactory; +import org.springframework.amqp.rabbit.connection.CorrelationData; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 操作日志消息队列-回调函数 + * + * @author ruoyi + */ +@Configuration +public class RabbitLogCallback { + + @Bean + public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory){ + RabbitTemplate rabbitTemplate = new RabbitTemplate(); + rabbitTemplate.setConnectionFactory(connectionFactory); + //设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数 + rabbitTemplate.setMandatory(true); + + rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { + @Override + public void confirm(CorrelationData correlationData, boolean ack, String cause) { + System.out.println("ConfirmCallback: "+"相关数据:"+correlationData); + System.out.println("ConfirmCallback: "+"确认情况:"+ack); + System.out.println("ConfirmCallback: "+"原因:"+cause); + } + }); + + rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() { + @Override + public void returnedMessage(ReturnedMessage returnedMessage) { + System.out.println("ReturnCallback: "+"消息:"+returnedMessage.getMessage()); + System.out.println("ReturnCallback: "+"回应码:"+returnedMessage.getReplyCode()); + System.out.println("ReturnCallback: "+"回应信息:"+returnedMessage.getReplyText()); + System.out.println("ReturnCallback: "+"交换机:"+returnedMessage.getExchange()); + System.out.println("ReturnCallback: "+"路由键:"+returnedMessage.getRoutingKey()); + } + }); + + return rabbitTemplate; + } + +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogDirect.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogDirect.java new file mode 100644 index 00000000..7f57ed88 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/mq/rabbit/RabbitLogDirect.java @@ -0,0 +1,58 @@ +package com.ruoyi.common.log.mq.rabbit; + +import org.springframework.amqp.core.Binding; +import org.springframework.amqp.core.BindingBuilder; +import org.springframework.amqp.core.DirectExchange; +import org.springframework.amqp.core.Queue; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 操作日志消息队列创建者-直连型交换机 + * + * @author ruoyi + */ +@Configuration +public class RabbitLogDirect { + + /** + * 队列名 + */ + public final static String queueName = "OperaLogDirectQueue"; + + /** + * 交换机名 + */ + public final static String exchangeName = "OperaLogDirectExchange"; + + /** + * 路由键名 + */ + public final static String routingKeyName = "OperaLogDirectRouting"; + + //队列 起名:OperaLogQueue + @Bean + public Queue operaLogQueue() { + // durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效 + // exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable + // autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。 + // return new Queue(queueName,true,true,false); + + //一般设置一下队列的持久化就好,其余两个就是默认false + return new Queue(queueName, true); + } + + // Direct交换机 起名:OperaLogDirectExchange + @Bean + DirectExchange operaLogDirectExchange() { + // return new DirectExchange(exchangeName,true,true); + return new DirectExchange(exchangeName, true, false); + } + + // 绑定 将队列和交换机绑定, 并设置用于匹配键:OperaLogDirectRouting + @Bean + Binding operaLogBindingDirect() { + return BindingBuilder.bind(operaLogQueue()).to(operaLogDirectExchange()).with(routingKeyName); + } + +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/ILogService.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/ILogService.java new file mode 100644 index 00000000..a0ddf780 --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/ILogService.java @@ -0,0 +1,16 @@ +package com.ruoyi.common.log.service; + +import com.ruoyi.system.api.domain.SysOperLog; + +/** + * 调用日志服务接口 + * + * @author ruoyi + */ +public interface ILogService { + + /** + * 保存系统日志记录 + */ + public void saveSysLog(SysOperLog sysOperLog); +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/AsyncLogService.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/AsyncLogService.java new file mode 100644 index 00000000..91eec19f --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/AsyncLogService.java @@ -0,0 +1,33 @@ +package com.ruoyi.common.log.service.impl; + +import com.ruoyi.common.log.service.ILogService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.system.api.RemoteLogService; +import com.ruoyi.system.api.domain.SysOperLog; + +/** + * 异步调用日志服务 + * + * @author ruoyi + */ +@Primary +@Service +public class AsyncLogService implements ILogService +{ + @Autowired + private RemoteLogService remoteLogService; + + /** + * 保存系统日志记录 + */ + @Async + @Override + public void saveSysLog(SysOperLog sysOperLog) + { + remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER); + } +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/RabbitLogService.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/RabbitLogService.java new file mode 100644 index 00000000..1287e67d --- /dev/null +++ b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/impl/RabbitLogService.java @@ -0,0 +1,68 @@ +package com.ruoyi.common.log.service.impl; + +import com.rabbitmq.client.Channel; +import com.ruoyi.common.core.constant.SecurityConstants; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.log.mq.rabbit.RabbitLogDirect; +import com.ruoyi.common.log.service.ILogService; +import com.ruoyi.system.api.RemoteLogService; +import com.ruoyi.system.api.domain.SysOperLog; +import org.springframework.amqp.rabbit.annotation.RabbitHandler; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.amqp.support.AmqpHeaders; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.handler.annotation.Header; +import org.springframework.stereotype.Component; + +/** + * MQ调用日志服务 + * + * @author ruoyi + */ +@Component +@RabbitListener(queues = RabbitLogDirect.queueName)//监听的队列名称 +public class RabbitLogService implements ILogService { + + @Autowired + private RabbitTemplate rabbitTemplate; + @Autowired + private RemoteLogService remoteLogService; + + /** + * 消息创造者 + * @param sysOperLog + */ + @Override + public void saveSysLog(SysOperLog sysOperLog) { + // 将消息保存队列 + rabbitTemplate.convertAndSend(RabbitLogDirect.exchangeName, RabbitLogDirect.routingKeyName, sysOperLog); + } + + /** + * 消息消费者 + * @param sysOperLog + * @param channel + * @param tag + * @Description 当一个消费者向 RabbitMQ 注册后,会建立起一个 Channel , + * RabbitMQ 会用 basic.deliver 方法向消费者推送消息, + * 这个方法携带了一个 delivery tag, 它代表了 RabbitMQ 向该 Channel 投递的这条消息的唯一标识 ID, + * 是一个单调递增的正整数,delivery tag 的范围仅限于 Channel + */ + @RabbitHandler + public void process(SysOperLog sysOperLog, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws Exception { + R result = remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER); + try { + if(result.getCode() == 200) { + // 第二个参数,手动确认可以被批处理,当该参数为 true 时,则可以一次性确认 delivery_tag 小于等于传入值的所有消息 + channel.basicAck(tag, true); + } else { + // 第二个参数,true会重新放回队列,所以需要自己根据业务逻辑判断什么时候使用拒绝 + channel.basicReject(tag, true); + } + } catch (Exception e) { + channel.basicReject(tag, false); + } + } + +} diff --git a/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring.factories b/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring.factories index 4a5ae7d5..3c9183b1 100644 --- a/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring.factories +++ b/ruoyi-common/ruoyi-common-log/src/main/resources/META-INF/spring.factories @@ -1,3 +1,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ - com.ruoyi.common.log.service.AsyncLogService,\ + com.ruoyi.common.log.service.impl.AsyncLogService,\ + com.ruoyi.common.log.service.impl.RabbitLogService,\ + com.ruoyi.common.log.mq.rabbit.RabbitLogDirect,\ + com.ruoyi.common.log.mq.rabbit.RabbitLogCallback,\ com.ruoyi.common.log.aspect.LogAspect From 3f5ebef64822018be2da242f130c9da5e831efdc Mon Sep 17 00:00:00 2001 From: zhanghongwei Date: Fri, 11 Mar 2022 10:20:42 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84AsyncLogService.java?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/log/service/AsyncLogService.java | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java diff --git a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java b/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java deleted file mode 100644 index 4f5986d1..00000000 --- a/ruoyi-common/ruoyi-common-log/src/main/java/com/ruoyi/common/log/service/AsyncLogService.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.ruoyi.common.log.service; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Service; -import com.ruoyi.common.core.constant.SecurityConstants; -import com.ruoyi.system.api.RemoteLogService; -import com.ruoyi.system.api.domain.SysOperLog; - -/** - * 异步调用日志服务 - * - * @author ruoyi - */ -@Service -public class AsyncLogService -{ - @Autowired - private RemoteLogService remoteLogService; - - /** - * 保存系统日志记录 - */ - @Async - public void saveSysLog(SysOperLog sysOperLog) - { - remoteLogService.saveLog(sysOperLog, SecurityConstants.INNER); - } -}