Feign遠程調用添加Token並設置服務降級

1 背景概述

    遠程調用:後臺管理服務需要調用實驗服務的某一接口,註冊中心顯示服務名如下:
在這裏插入圖片描述

2 實驗部分(被調用方)

@ApiOperation(value = "刪除一個實驗", httpMethod = "DELETE")
@DeleteMapping("/jobs")
public boolean deleteExperiment(@RequestParam("experimentId")int experimentId,
                                HttpServletRequest request, HttpServletResponse response) {
    int uid = UidCheckSingleTon.identityCheck(request);
    int isSuper = request.getHeader("Gw-Super")!=null? Integer.parseInt(request.getHeader("Gw-Super")):0;
    int record = experimentJobService.deleteExperimentJob(experimentId,uid,isSuper);
    if(record > 0) {
        return true;
    }else {
        throw new BusinessException(BusinessExceptionEnum.EXPERIMENT_DELETE_FAILED);
    }
}

3 後臺管理部分(調用方)

3.1 編寫遠程調用接口
@FeignClient(value = "srv-dmp-experiment-dev}")
public interface TaskDeleteService {

    /**
     * 遠程接口 刪除實驗任務相關信息
     * @param experimentId experimentId
     * @return base model
     * @throws Exception ex
     */
    @DeleteMapping("/dmp/experiment/jobs")
    boolean deleteExperiment(@RequestParam("experimentId")int experimentId) throws Exception;
}
3.2 在controller中使用
@Resource
private TaskDeleteService taskDeleteService;

@ApiOperation(value = "根據任務的實驗主鍵ID刪除相關記錄")
@ApiImplicitParams({
        @ApiImplicitParam(name = "experimentId", value = "experimentId", dataType = "Integer", example = "1"),
})
@DeleteMapping(value = "/tasks/{experimentId}")
public boolean deleteTaskInfo(@PathVariable(value = "experimentId") int experimentId) throws Exception {
    if (!taskDeleteService.deleteExperiment(experimentId)){
        throw new ManageBusinessException(ManageExceptionEnum.DELETE_EXPERIMENT_RPC_FAILED);
    }
    return true;
}
3.3 解決遠程調用時的token驗證

    Feign提供了一個接口:RequestInterceptor。只要實現該攔截器接口,重寫apply方法,再將該配置實現類交由Spring容器管理即可。比如我們項目中網關會對註冊用戶進行token校驗,只有請求header中的Gw-token和Gw-Uid合法纔會放行,故添加如下設置,再在調用方的@FeignClient註解裏引入該配置(configuration = TaskDeleteFeignConfig.class),這樣就實現了把當前請求的token放到了feign請求頭上:

@Configuration
public class TaskDeleteFeignConfig implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return;
        }
        HttpServletRequest request = attributes.getRequest();
        //添加token
        requestTemplate.header("Gw-Token", request.getHeader("Gw-Token"));
        requestTemplate.header("Gw-Uid", request.getHeader("Gw-Uid"));
        requestTemplate.header("Gw-Super", "1");
    }
}
3.4 服務降級

    有兩種方式可實現,第一種:對Feign服務接口添加實現類並註冊到IOC容器(@Component不能缺失,否則會報錯 No fallbackFactory instance of type class),在該類中定義對應的降級方法,然後在調用方Feign服務接口中的@FeignClient註解裏添加fallback屬性(name = “srv-dmp-experiment-dev”, fallback=****.class);第二種:用FallbackFactory,定義一個FallbackFactory的實現類,重寫create方法,再在Feign服務接口中的@FeignClient註解裏添加FallbackFactory實現類(name = “srv-dmp-experiment-dev”, fallbackFactory = ****.class)。

@Component
@Slf4j
public class TaskDeleteServiceFallbackImpl implements FallbackFactory<TaskDeleteService> {

    @Override
    public TaskDeleteService create(Throwable cause) {
        log.info(cause.getMessage());
        return experimentId -> {
            log.info("遠程調用實驗experimentId: {}刪除失敗!",experimentId);
            return false;
        };
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章