SpringCloud RestTemplate+HTTP实现微服务跨服务接口调用

前言:我们知道SpringCloud中服务调用可以用Fegin本地客户端和RestTemplate模板的方式,如果是Dubbo则是分布式的RPC则轻松搞定,这里介绍的是Cloud模板的方式。性能不是很好,为什么大家可以思考一下!

背景:各服务都注册在Eureka上,彼此独立部署(注意不是独立部署,用模板就没那么多讲究了),现需要在一个服务调用另一个服务的接口,原因是视图改造,以往的开发人员服务间沟通居然采用视图的形式,视图这种东西基本被时代淘汰了。

一、在Eueka上找到需要调用的服务,记下服务名

SpringCloud RestTemplate+HTTP实现微服务跨服务接口调用_第1张图片

二、编写RestTemplateService

在config类配置一下模板,@Bean注入进容器:

    /**
     * resttemplate客户端
     * 
     * @return
     */
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
        return new HystrixCommandAspect();
    }
@Service
public class RestTemplateService {

    private ZSmartLogger zsmartLogger = ZSmartLogger.getLogger(this.getClass(), LogCodeUtil.getModule(this.getClass()));
    /**
     * 注入门户服务名,默认不需要配置,值为COMMON-SYSTEM
     */
    @Value("${comsystem.service.name:COMMON-SYSTEM}")
    private String comsystemServiceName;


        /**
     * post方式请求,当前用户请求安全服务,仅限用注册中心的时候可以调用
     * @param postObject 请求参数
     * @param module 模块名称
     * @param header 请求头
     * @param 
     * @return
     */
    public  T postSmartSafePortalService(Object postObject, String module, Map header) {
        List
headers = Lists.newArrayList(); Map safeHeader = Maps.newHashMap(); safeHeader.put("signature-sessionid", header.get("signature-sessionid")); safeHeader.put("Content-Type", "application/json"); Iterator> iterator = safeHeader.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry entry = iterator.next(); if (Objects.nonNull(entry.getValue())) { BasicHeader basicHeader = new BasicHeader(entry.getKey(), entry.getValue()); headers.add(basicHeader); } } zsmartLogger.info(LogCodeUtil.getTranId(KeyValues.MODULE_NAME), "postSmartSafePortalService-postObject:{}", JsonUtil.toJson(postObject)); String url = "http://" + smartSafePortalServiceName.trim() + "/smartsafe/" + module; return this.postJsonByObject(headers, postObject, url); } /** * 模拟HTTP请求,不对外暴露 * * @param headers 请求头 * @param postObject 请求参数 * @param url 请示服务路径 * @return 返回参数 */ private T postJsonByObject(List
headers, Object postObject, String url) { HttpHeaders httpHeaders = new HttpHeaders(); for (Header header : headers) { httpHeaders.add(header.getName(), header.getValue()); } MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); httpHeaders.setContentType(type); httpHeaders.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity formEntity = new HttpEntity(new Gson().toJson(postObject), httpHeaders); ResponseEntity postForEntity = this.restTemplate.postForEntity(url, formEntity, String.class); String responseBody = postForEntity.getBody(); return (T) JSON.parseObject(responseBody); }

三、具体需要调用的别的服务的接口,比如这里需要在我的服务调用安全服务的接口getListAllSafeSensitiveField

@Service
public class SmartSafePortalService {

    @Autowired
    private RestTemplateService restTemplateService;

    private ZSmartLogger zsmartLogger = ZSmartLogger.getLogger(this.getClass(), LogCodeUtil.getModule(this.getClass()));

    /**
     * 敏感字段查询
     * @param params
     * @param header
     * @return
     */
    public Result> getListAllSafeSensitiveField(Map params, Map header) {
        // 别的服务的路径
        String module = "SafeSensitiveFieldController/xxxxx";
        zsmartLogger.info(LogCodeUtil.getTranId(KeyValues.MODULE_NAME), "getListAllSafeSensitiveField-params:{}", params);
        Map resultMap = restTemplateService.postSmartSafePortalService(params, module, header);

        String resultCode = MapParamUtil.getStringValue(resultMap, "resultCode");
        String resultMsg = MapParamUtil.getStringValue(resultMap, "resultMsg");
        Map resultObject = (Map) resultMap.get("resultObject");
        zsmartLogger.info(LogCodeUtil.getTranId(KeyValues.MODULE_NAME), "resultObject:{}", resultObject);
        if (null == resultObject) {
            return Result.fail(resultMsg);
        }
        Map pageMap = (Map) resultObject.get("pageInfo");
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPageCount((Integer) pageMap.get("pageCount"));
        pageInfo.setTotal((Integer) pageMap.get("total"));
        pageInfo.setPageIndex((Integer) pageMap.get("pageIndex"));
        pageInfo.setPageSize((Integer) pageMap.get("pageSize"));
        Integer records = MapParamUtil.getIntValue(resultObject, "records");
        List list = (List) resultObject.get("rows");
        zsmartLogger.info(LogCodeUtil.getTranId(KeyValues.MODULE_NAME), "rows-list:{}", list);

        PageVO pageVO = new PageVO();
        pageVO.setPage(pageInfo.getPageIndex());
        pageVO.setRowNum(pageInfo.getPageSize());
        pageVO.setRows(MapParamUtil.mapListToObjectList(list, SafeSensitiveFieldDto.class));
        pageVO.setRecords(records);
        pageVO.setTotal(pageInfo.getTotal());
        if (KeyValues.SUCCESS.equalsIgnoreCase(resultCode)) {
            return Result.success(pageVO, resultMsg);
        }
        return Result.fail(resultMsg);
    }
}

到这里就实现了从本服务调用别的服务的具体接口拿到该接口的数据了,我们在本服务只需要拿到别的方服务的返回值结构,实体,就可以自己封装成一个取数接口,供本服务调用。本服务需要调用安全服务的该接口,直接调用该方法即可。同理调用安全服务的其他方法也可以这样写

四、开启本地PostMan测试调用远程服务的配置

1、

(1)配置hosts

位置:C:\Windows\System32\drivers\etc

例如我要配置167的IP:

(2)配置端口注册到注册中心

为区别已经注册上注册中心的端口号,端口号要修改一下

例如原来本地localhost调试的:

smartservice.port=9280
smartweb.port=9284
center.port=8900
gateway.port=9286

改成:

smartservice.port=9281
smartweb.port=9285
center.port=8900
gateway.port=9287

(3)配置注册中心地址

原来的是:

eureka.instance.hostname=localhost

改成远程的注册中心,比如我要在167开发环境的测试:

eureka.instance.hostname=172.21.72.167

(4)改服务名,避免冲突:

例如,原来smartservice的服务名可以改成:

spring.application.name=smartservice2

其他几个 例如smartweb、center、gateway的类似

(5)改serviceId和postman的请求path(可选)

例如原来的:

zuul.routes.smartservice.path=/smartweb/smartservice/**
zuul.routes.smartservice.serviceId=smartservice
zuul.routes.smartweb.path=/**
zuul.routes.smartweb.serviceId=smartweb

可以改成:

zuul.routes.smartservice.path=/smartweb2/smartservice2/**
zuul.routes.smartservice.serviceId=smartservice2
zuul.routes.smartweb.path=/**
zuul.routes.smartweb.serviceId=smartweb2

2、

eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://localhost:8901/eureka/

改成:
eureka.instance.hostname=具体环境IP
eureka.client.serviceUrl.defaultZone=http://具体环境IP:8900/eureka/

此外端口号和服务名也可以修改 
postman直接localhost:端口号/controller路径 访问即可

你可能感兴趣的:(SpringCloud,spring,cloud,微服务,http)