1. 程式人生 > >springcloud中servcie層調用fegin異常以及異步方法的實現

springcloud中servcie層調用fegin異常以及異步方法的實現

需要 npoi zed type contex ads ews 為什麽 oba

近日在做業務上的短信推送和APP消息推送,通過調用別的模塊的接口來實現,在springcloud中通過fegin進行調用。這裏要說明的事情並不是如何開發推送功能,而是在調試過程中碰到的一些小問題。
我把消息推送之前的業務處理代碼以及調用推送服務的代碼都放在方法pushByAppAndShortMessage()中,然後把這個方法單獨的放在crmservice裏面。由於業務處理,pushByAppAndShortMessage中需要用到別的service,就不得不在crmservice中進行大量的autowired。代碼如下:

package cn.appliedata.operate.service;
import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import cn.appliedata.common.ResponseWrapper; import cn.appliedata.message.Message;
import cn.appliedata.message.Message.Type; import cn.appliedata.model.account.UserAccount; import cn.appliedata.operate.bean.Supplieres; import cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO; import cn.appliedata.operate.enums.SupplierSuggestionEnum; import cn.appliedata.operate.feignClient.AccountFeignService;
import cn.appliedata.operate.feignClient.MessageFeignService; import cn.appliedata.operate.feignClient.SmsCodeFeignService; import cn.appliedata.operate.mapper.crm.PartsDao; import cn.appliedata.operate.mapper.operate.OperateTaichiDao; import cn.appliedata.operate.util.ConstantUtil; import lombok.extern.slf4j.Slf4j; /** * @author :ayfei */ @Service @Slf4j public class CrmService { @Autowired private MessageFeignService messageFeignService; @Autowired private SmsCodeFeignService smsCodeFeignService; @Autowired private AccountFeignService accountFeignService; @Autowired private StocksiteService stocksiteService; @Autowired private PartsService partsService; /* * 消息推送[APP、短信] */ @Async public void pushByAppAndShortMessage(Integer i,Integer senderFlag,SaveFeedbackDTO saveFeedbackDTO){ log.info("log推送1:索引index = "+i); Message message = new Message(); // 創建APP推送消息體 message.setType(Type.ORDER); // 消息類型不能為空 if(senderFlag == ConstantUtil.INTNUM1){ // 1 服務人員 發送,推送給 供應商 log.info("log推送:推送給供應商"); //有新增、有修改,獲取供應商的 accountcode 和 手機號 String type = ""; String feedBackName = "";//異常反饋單號 if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM1){ type = "新增"; message.setContent("您有一條"+type+"異常反饋單待處理,請前往工具->運維反饋進行處理"); //內容不能為空 }else if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM2){ type = "更新"; Map<String,String> serviceWorkerMap = partsService.getServiceWorkerInfo(saveFeedbackDTO.getFeedbackId()); feedBackName = serviceWorkerMap.get("feedBackName"); //當前的異常反饋單號 message.setContent("您有一條"+type+"異常反饋單待處理,異常反饋單號:"+feedBackName+",請前往工具->運維反饋進行處理"); //內容不能為空 } //根據供應商id獲取責任人id和電話 String ownerId = null; String ownerPhone = null; List<Supplieres> supplierSelect = stocksiteService.supplierSelect(null, null, saveFeedbackDTO.getSupplierId()); if(supplierSelect == null || supplierSelect.get(0) == null){ log.info("根據供應商id獲取責任人信息為空"); return; }else{ ownerId = supplierSelect.get(0).getOwnerId(); ownerPhone = supplierSelect.get(0).getNewSupplierCall(); } if(ownerPhone != null){ try { //短信推送供應商 String shortMessage = "您有一條"+type+"異常反饋單:"+feedBackName+"待處理,請登錄APP前往工具->運維反饋進行處理。"; //ResponseWrapper sendArbitrarilyMsg = smsCodeFeignService.sendArbitrarilyMsg(ownerPhone, "", shortMessage);//給服務人員發送短信 ResponseWrapper sendArbitrarilyMsg = smsCodeFeignService.sendArbitrarilyMsg("18337117299", "", shortMessage);//給服務人員發送短信 if(!sendArbitrarilyMsg.isSuccess()){ log.info("異常反饋單號:"+feedBackName+"的消息短信推送供應商失敗");//短信發送失敗 } } catch (Exception e) { log.info("異常反饋單號:"+feedBackName+"的消息短信推送供應商出現異常"); } try { //APP推送供應商 獲取供應商賬號的 accountcode ResponseWrapper<UserAccount> accountByMobile = accountFeignService.getAccountByMobile(ownerPhone); if(accountByMobile == null || accountByMobile.getObj() == null){ log.info("獲取遠程供應商賬號信息異常/返回信息為空"); return; } message.setTo(accountByMobile.getObj().getAccountCode()); // message.setSubject(type+"異常反饋單信息"); //標題不能為空 message.setSummary("您有一條"+type+"異常反饋單信息,註意查收");//消息摘要不能為空 ResponseWrapper respon = messageFeignService.addMessage(message); //APP推送給供應商的賬號 if(!respon.isSuccess()){ log.info("異常反饋單新增、修改信息,APP推送供應商失敗");//APP失敗 } } catch (Exception e) { log.info("異常反饋單新增、修改信息,APP推送供應商出現異常"); } }else{ log.info("供應商電話為null!,無法推送"); } }else if(senderFlag == ConstantUtil.INTNUM2){ //2 供應商 發送, 推送給 服務人員 log.info("log推送:推送給服務人員"); //只有修改功能,獲取服務人員的accountcode 和 手機號 String feedbackidStr = saveFeedbackDTO.getFeedbackId(); Map<String,String> serviceWorkerMap = partsService.getServiceWorkerInfo(feedbackidStr);//根據異常反饋單id獲取對應服務單對應的服務人員信息 if(serviceWorkerMap == null){ log.info("根據異常反饋單id:"+saveFeedbackDTO.getFeedbackId()+"獲取到的服務人員信息對象為null"); return; } String serviceWorkerMobile = serviceWorkerMap.get("mobile"); //服務人員電話 String serviceWorkerId = serviceWorkerMap.get("id"); //服務人員id String serviceWorkerName = serviceWorkerMap.get("name"); //服務人員姓名 String feedBackName = serviceWorkerMap.get("feedBackName"); //當前的異常反饋單號 //獲取服務人員賬號的 accountcode try { ResponseWrapper<UserAccount> accountByMobile = accountFeignService.getAccountByMobile(serviceWorkerMobile); if(accountByMobile == null || accountByMobile.getObj() == null){ log.info("獲取遠程供應商賬號信息異常/返回信息為空"); return; } message.setTo(accountByMobile.getObj().getAccountCode()); message.setSubject("供應商反饋意見信息"); //標題不能為空 message.setSummary("您有一條供應商反饋信息,請註意查收");//消息摘要不能為空 message.setContent("異常反饋單號:"+feedBackName+",已由供應商填寫反饋信息。供應商意見:"+ SupplierSuggestionEnum.getNameStatic(saveFeedbackDTO.getSuggestion()) +";供應商意見備註:"+saveFeedbackDTO.getSuggestionMemo()); //內容不能為空 ResponseWrapper respon = messageFeignService.addMessage(message);//APP推送給服務人員的賬號 if(!respon.isSuccess()){ log.info("異常反饋單號:"+feedBackName+"的信息變更,APP推送服務人員失敗");//APP失敗 } } catch (Exception e) { log.info("異常反饋單號:"+feedBackName+"的信息變更,APP推送服務人員出現異常");//APP失敗 } } } }

然後再controller中進行調用crmservice的pushByAppAndShortMessage()方法的時候,出現如下異常:

2019-01-10 13:29:34,762 ERROR (FeignClientsHeadersTransfer.java:60)- headers復制出錯!
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
     at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
     at cn.appliedata.feign.FeignClientsHeadersTransfer.lambda$requestInterceptor$0(FeignClientsHeadersTransfer.java:26)
     at feign.SynchronousMethodHandler.targetRequest(SynchronousMethodHandler.java:158)
     at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:88)
     at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
     at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
     at com.sun.proxy.$Proxy141.addMessage(Unknown Source)
     at cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(CrmService.java:97)
     at cn.appliedata.operate.service.CrmService$$FastClassBySpringCGLIB$$7d315874.invoke(<generated>)
     at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
     at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
     at org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspect.traceBackgroundThread(TraceAsyncAspect.java:69)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627)
     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
     at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
     at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
     at org.springframework.cloud.sleuth.instrument.async.SpanContinuingTraceRunnable.run(SpanContinuingTraceRunnable.java:52)
     at java.lang.Thread.run(Thread.java:748)
2019-01-10 13:29:34,763 INFO (AbstractApplicationContext.java:583)- Refreshing org.spring[email protected]3b9a0944: startup date [Thu Jan 10 13:29:34 GMT+08:00 2019]; parent: org.springframework.boot[email protected]66273da0
2019-01-10 13:29:34,786 INFO (AutowiredAnnotationBeanPostProcessor.java:155)- JSR-330 ‘javax.inject.Inject‘ annotation found and supported for autowiring
2019-01-10 13:29:34,803 INFO (ChainedDynamicProperty.java:115)- Flipping property: service-message.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-01-10 13:29:34,804 INFO (ShutdownEnabledTimer.java:58)- Shutdown hook installed for: NFLoadBalancer-PingTimer-service-message
2019-01-10 13:29:34,805 INFO (BaseLoadBalancer.java:192)- Client: service-message instantiated a LoadBalancer: DynamicServerListLoadBalancer:{NFLoadBalancer:name=service-message,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:null
2019-01-10 13:29:34,805 INFO (DynamicServerListLoadBalancer.java:222)- Using serverListUpdater PollingServerListUpdater
2019-01-10 13:29:34,806 INFO (DynamicServerListLoadBalancer.java:150)- DynamicServerListLoadBalancer for client service-message initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=service-message,current list of Servers=[],Load balancer stats=Zone stats: {},Server stats: []}ServerList:org.springf[email protected]6b044553
2019-01-10 13:29:34,878 ERROR (SimpleAsyncUncaughtExceptionHandler.java:37)- Unexpected error occurred invoking async method ‘public void cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(java.lang.Integer,java.lang.Integer,cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO)‘.
java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: service-message
     at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:71)
     at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:97)
     at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
     at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
     at com.sun.proxy.$Proxy141.addMessage(Unknown Source)
     at cn.appliedata.operate.service.CrmService.pushByAppAndShortMessage(CrmService.java:97)
     at cn.appliedata.operate.service.CrmService$$FastClassBySpringCGLIB$$7d315874.invoke(<generated>)
     at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
     at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:738)
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
     at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
     at org.springframework.cloud.sleuth.instrument.async.TraceAsyncAspect.traceBackgroundThread(TraceAsyncAspect.java:69)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:498)
     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627)
     at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616)
     at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
     at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
     at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
     at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115)
     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
     at org.springframework.cloud.sleuth.instrument.async.SpanContinuingTraceRunnable.run(SpanContinuingTraceRunnable.java:52)
     at java.lang.Thread.run(Thread.java:748)
Caused by: com.netflix.client.ClientException: Load balancer does not have available server for client: service-message
     at com.netflix.loadbalancer.LoadBalancerContext.getServerFromLoadBalancer(LoadBalancerContext.java:483)
     at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:184)
     at com.netflix.loadbalancer.reactive.LoadBalancerCommand$1.call(LoadBalancerCommand.java:180)
     at rx.Observable.unsafeSubscribe(Observable.java:10151)
     at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:94)
     at rx.internal.operators.OnSubscribeConcatMap.call(OnSubscribeConcatMap.java:42)
     at rx.Observable.unsafeSubscribe(Observable.java:10151)
     at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber$1.call(OperatorRetryWithPredicate.java:127)
     at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:73)
     at rx.internal.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.schedule(TrampolineScheduler.java:52)
     at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:79)
     at rx.internal.operators.OperatorRetryWithPredicate$SourceSubscriber.onNext(OperatorRetryWithPredicate.java:45)
     at rx.internal.util.ScalarSynchronousObservable$WeakSingleProducer.request(ScalarSynchronousObservable.java:276)
     at rx.Subscriber.setProducer(Subscriber.java:209)
     at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:138)
     at rx.internal.util.ScalarSynchronousObservable$JustOnSubscribe.call(ScalarSynchronousObservable.java:129)
     at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
     at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
     at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
     at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
     at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
     at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
     at rx.Observable.subscribe(Observable.java:10247)
     at rx.Observable.subscribe(Observable.java:10214)
     at rx.observables.BlockingObservable.blockForSingle(BlockingObservable.java:444)
     at rx.observables.BlockingObservable.single(BlockingObservable.java:341)
     at com.netflix.client.AbstractLoadBalancerAwareClient.executeWithLoadBalancer(AbstractLoadBalancerAwareClient.java:112)
     at org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:63)
     ... 25 common frames omitted
2019-01-10 13:29:35,024 INFO (ChainedDynamicProperty.java:115) - Flipping property: service-sms-code.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-01-10 13:29:35,648 INFO (ChainedDynamicProperty.java:115)- Flipping property: service-account.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

這篇文章給了一些思路:https://segmentfault.com/a/1190000014418250
大致意思就是,fegin底調用了訪問了RequestContextHolder.currentRequestAttributes()導致,因此在service層方法裏頭調用該方法要慎重,為了避免出錯,可以再封裝一下。所以我認為是servvice層代用fegin導致的。於是決定把這個方法放到工具類代碼中(結合以前遇到的utils中註入bean),
代碼如下:然後再controller中調用工具類中此方法,得以實現。正常運行。

package cn.appliedata.operate.util;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import cn.appliedata.common.ResponseWrapper;
import cn.appliedata.message.Message;
import cn.appliedata.message.Message.Type;
import cn.appliedata.model.account.UserAccount;
import cn.appliedata.operate.bean.Supplieres;
import cn.appliedata.operate.bean.crmFlow.SaveFeedbackDTO;
import cn.appliedata.operate.enums.SupplierSuggestionEnum;
import cn.appliedata.operate.feignClient.AccountFeignService;
import cn.appliedata.operate.feignClient.MessageFeignService;
import cn.appliedata.operate.feignClient.SmsCodeFeignService;
import cn.appliedata.operate.service.PartsService;
import cn.appliedata.operate.service.StocksiteService;
import lombok.extern.slf4j.Slf4j;
/**
 * @author      :ayfei
 * @createTime  :2019年1月10日下午2:31:41
 * @description :
 */
@Slf4j
@Component
public class PushByAppAndShortMessageUtil {

    @Autowired
    private MessageFeignService messageFeignService;
    @Autowired
    private SmsCodeFeignService smsCodeFeignService;
    @Autowired
    private AccountFeignService accountFeignService;
    @Autowired
    private StocksiteService stocksiteService;
    @Autowired
    private PartsService partsService;
    
    private static PushByAppAndShortMessageUtil  utils ; 
    
    @PostConstruct     //關鍵二   通過@PostConstruct 和 @PreDestroy 方法 實現初始化和銷毀bean之前進行的操作
    public void init() {  
        utils = this;  
        utils.messageFeignService = this.messageFeignService;   // 初使化時將已靜態化的messageFeignService實例化
        utils.smsCodeFeignService = this.smsCodeFeignService;
        utils.accountFeignService = this.accountFeignService;
        utils.stocksiteService    = this.stocksiteService;
        utils.partsService        = this.partsService;
    }
    
    /*
       * 消息推送[APP、短信]
     */
    @Async
    public static void pushByAppAndShortMessage(Integer i,Integer senderFlag,SaveFeedbackDTO saveFeedbackDTO){
        log.info("log推送1:索引index = "+i);
        Message message = new Message();            //  創建APP推送消息體
        message.setType(Type.ORDER);                //  消息類型不能為空
        if(senderFlag == ConstantUtil.INTNUM1){     //  1  服務人員  發送,推送給 供應商
            log.info("log推送:推送給供應商");
            //有新增、有修改,獲取供應商的    accountcode  和   手機號
            String type = "";
            String feedBackName = "";//異常反饋單號
            if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM1){
                type = "新增";
                message.setContent("您有一條"+type+"異常反饋單待處理,請前往工具->運維反饋進行處理");     //內容不能為空
            }else if(saveFeedbackDTO.getType() == ConstantUtil.INTNUM2){
                type = "更新";
                Map<String,String> serviceWorkerMap = utils.partsService.getServiceWorkerInfo(saveFeedbackDTO.getFeedbackId());
                feedBackName = serviceWorkerMap.get("feedBackName"); //當前的異常反饋單號
                message.setContent("您有一條"+type+"異常反饋單待處理,異常反饋單號:"+feedBackName+",請前往工具->運維反饋進行處理");     //內容不能為空
            }
            //根據供應商id獲取責任人id和電話
            String ownerId = null;
            String ownerPhone = null;
            List<Supplieres> supplierSelect = utils.stocksiteService.supplierSelect(null, null, saveFeedbackDTO.getSupplierId());
            if(supplierSelect == null || supplierSelect.get(0) == null){
                log.info("根據供應商id獲取責任人信息為空");
                return;
            }else{
                ownerId = supplierSelect.get(0).getOwnerId();
                ownerPhone = supplierSelect.get(0).getNewSupplierCall();
            }
            if(ownerPhone != null){
                try {
                    //短信推送供應商
                    String shortMessage = "您有一條"+type+"異常反饋單:"+feedBackName+"待處理,請登錄APP前往工具->運維反饋進行處理。";
                    //ResponseWrapper sendArbitrarilyMsg = utils.sendArbitrarilyMsg(ownerPhone, "", shortMessage);//給服務人員發送短信
                    ResponseWrapper sendArbitrarilyMsg = utils.smsCodeFeignService.sendArbitrarilyMsg("18337117299", "", shortMessage);//給服務人員發送短信
                    if(!sendArbitrarilyMsg.isSuccess()){
                        log.info("異常反饋單號:"+feedBackName+"的消息短信推送供應商失敗");//短信發送失敗
                    }
                } catch (Exception e) {
                    log.info("異常反饋單號:"+feedBackName+"的消息短信推送供應商出現異常");
                }
                try {
                    //APP推送供應商   獲取供應商賬號的   accountcode 
                    ResponseWrapper<UserAccount> accountByMobile = utils.accountFeignService.getAccountByMobile(ownerPhone);
                    if(accountByMobile == null || accountByMobile.getObj() == null){
                        log.info("獲取遠程供應商賬號信息異常/返回信息為空");
                        return;
                    }
                    message.setTo(accountByMobile.getObj().getAccountCode());               //
                    message.setSubject(type+"異常反饋單信息");     //標題不能為空
                    message.setSummary("您有一條"+type+"異常反饋單信息,註意查收");//消息摘要不能為空
                    ResponseWrapper respon = utils.messageFeignService.addMessage(message); //APP推送給供應商的賬號
                    if(!respon.isSuccess()){
                        log.info("異常反饋單新增、修改信息,APP推送供應商失敗");//APP失敗
                    }
                } catch (Exception e) {
                    log.info("異常反饋單新增、修改信息,APP推送供應商出現異常");//APP異常
                }
            }else{
                log.info("供應商電話為null!,無法推送");
            }
        }else if(senderFlag == ConstantUtil.INTNUM2){   //2 供應商 發送, 推送給 服務人員
            log.info("log推送:推送給服務人員");
            //只有修改功能,獲取服務人員的accountcode 和  手機號
            String feedbackidStr = saveFeedbackDTO.getFeedbackId();
            Map<String,String> serviceWorkerMap = utils.partsService.getServiceWorkerInfo(feedbackidStr);//根據異常反饋單id獲取對應服務單對應的服務人員信息
            if(serviceWorkerMap == null){
                log.info("根據異常反饋單id:"+saveFeedbackDTO.getFeedbackId()+"獲取到的服務人員信息對象為null");
                return;
            }
            String serviceWorkerMobile  = serviceWorkerMap.get("mobile");       //服務人員電話
            String serviceWorkerId      = serviceWorkerMap.get("id");           //服務人員id
            String serviceWorkerName    = serviceWorkerMap.get("name");         //服務人員姓名
            String feedBackName         = serviceWorkerMap.get("feedBackName"); //當前的異常反饋單號
            //獲取服務人員賬號的 accountcode 
            try {
                ResponseWrapper<UserAccount> accountByMobile = utils.accountFeignService.getAccountByMobile(serviceWorkerMobile);
                if(accountByMobile == null || accountByMobile.getObj() == null){
                    log.info("獲取遠程供應商賬號信息異常/返回信息為空");
                    return;
                }
                message.setTo(accountByMobile.getObj().getAccountCode());
                message.setSubject("供應商反饋意見信息");              //標題不能為空
                message.setSummary("您有一條供應商反饋信息,請註意查收");//消息摘要不能為空
                message.setContent("異常反饋單號:"+feedBackName+",已由供應商填寫反饋信息。供應商意見:"+ 
                                    SupplierSuggestionEnum.getNameStatic(saveFeedbackDTO.getSuggestion())
                                    +";供應商意見備註:"+saveFeedbackDTO.getSuggestionMemo());     //內容不能為空
                ResponseWrapper respon = utils.messageFeignService.addMessage(message);//APP推送給服務人員的賬號
                if(!respon.isSuccess()){
                    log.info("異常反饋單號:"+feedBackName+"的信息變更,APP推送服務人員失敗");//APP失敗
                }
            } catch (Exception e) {
                log.info("異常反饋單號:"+feedBackName+"的信息變更,APP推送服務人員出現異常");//APP異常
            }
            
        }
    }
    
}


===============================================

上述的這個方法,業務上屬於消息推送,我決定讓他異步執行。使用註解實現。但是一直沒有生效,結合文章:
https://blog.csdn.net/qq_34545192/article/details/80484780,主要是因為第三點我沒有做到!!!
在@SpringBootApplication啟動類 添加註解@EnableAsync
異步方法使用註解@Async ,返回值為void或者Future
切記一點 ,異步方法和調用方法一定要**** 寫在不同的類中 ****,如果寫在一個類中,是沒有效果的

為什麽第三點會沒有效果,那是因為Spring像@Transcation @Async等這些都是使用了動態代理,由Proxy$對象去調用被增強方法,重點來了:方法裏想用增強方法(博主說的第三點)則需要得到當前的Proxy$對象 詳情請看 ->Spring的 AopContext.currentProxy()方法

springcloud中servcie層調用fegin異常以及異步方法的實現