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;
};
}
}