Spring Cloud拉取注册Eureka服务和RestTemplate调其他接口

个人理解

公司临近过年放假,我所在的项目有这么一个实现,那就是如何维护Oracle数据库不同用户的一张OrgBelong表的数据一致???(这里补充一下,我个人也是第一次使用Oracle数据库,也不是特别熟练Oracle数据库,Oracle就只有一个库,这个库里有不同的用户,不同的用户可以看到不同的表,Oracle数据库中的不同的用户就相当于Mysql中不同的数据库)。但是由于这个项目是针对银行的业务,项目经理说银行那边的技术要求不支持使用Mq,其实这种场景最适合的就是使用消息队列来实现。当时我还建议使用Oracle主从复制,同步数据,这里不现实,因为我们的需求是只要实现这一张OrgBelong表的数据统一。那么我就使用了另外一个思路,就是从注册中心获取所有注册到Eureka的服务,从中过滤掉网关(AGS_SERVER),配置中心(ASCC-SERVER),还有权限控制(AOAS-SERVER),以及当前所在的模块(xxxxx-SERVER)–原因是逻辑在这里实现,不需要重复通过服务调用,我在当前请求的模块中将数据增量的数据打包成报文,剩下的模块中需要都要准备一个接口用于保存增量数据,通过restTemplate来广播发送到其他微服务模块的接口来实现这一业务场景,这种实现方式会很慢,但是我的技术也十分菜鸡,如果各位大佬有更合理的实现方式(其实也就是模拟消息队列的实现)可以评论,我会关注的,谢谢你的浏览,下面我来开始我的代码实现之旅了,首先让我们先来看看如何从注册拉取微服务模块,以及RestTemplate的使用吧。。

拉取注册中心所有服务

启动注册中心Eureka,和两个微服务模块(测试用,那就随意启动两个了,不用在意,重点是下面代码)

在这里插入图片描述

使用DiscoveryClient获取

	//获取一些配置的信息,得到具体的微服务!
    @Autowired
    private DiscoveryClient client;
	//注册进来的微服务~,获取一些消息~
    @GetMapping("/dept/discovery")
    public Object discovery(){
    
    
        //获取微服务列表的清单
        List<String> services = client.getServices();
        //打印信息:discovery=>services:[springcloud-provider-dept, springcloud-zuul]
        System.out.println("discovery=>services:"+services);

        //得到一个具体的微服务信息,通过具体的微服务id;
        // 通过写在application.yml中配置的spring.application.name=springcloud-provider-dept;
        List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");

        for (ServiceInstance instance : instances) {
    
    
            System.out.println(
                    instance.getHost()+"\t"+
                    instance.getPort()+"\t"+
                    instance.getUri()+"\t"+
                    instance.getServiceId()
            );
        }
        return this.client;
    }

测试结果

  • 控制台信息
    在这里插入图片描述
  • 浏览器信息
    在这里插入图片描述

RestTemlate封装请求头HttpHeaders实现调用

这里可以替代RestTemlate的产品有OkHttpClient,WebClient,至于三者的区别,可以百度,这里不做过多解释,下面以RestTemlate为例。

	// RestTemplate .... 供我们直接调用就可以了! 注册到Spring中
    @Autowired
    private RestTemplate restTemplate; //提供多种便捷访问远程http服务的方法,简单的Restful服务模板~

    //Ribbon。我们这里的地址,应该是一个变量,通过服务名来访问
    private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";

    @RequestMapping("/consumer/dept/add")
    public String add(Dept dept){
    
    
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        headers.add("UserId", "admin");

        HttpEntity<String> formEntity = new HttpEntity<String>(JSON.toJSONString(dept), headers);
        String s = restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", formEntity, String.class);
        return s;
    }

    @RequestMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id){
    
    
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
    }

我的代码实现

以下代码仅供参考,在实际工作中是不可以直接复制粘贴改参数的,需要你看懂之后然后进行根据思路修改,后期有更好的解决方案我会在博客后面声明的,谢谢你的浏览,代码有什么问题可以评论区留言,毕竟下面这段代码我是凭借记忆高度还原的。

import com.alibaba.fastjson.JSON;
import com.kuang.springcloud.pojo.Dept;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 模拟消息队列刷新服务
 */
public class RefreshServiceUtils {
    
    

    /**
     * 模拟消息队列刷新服务的重载函数
     * @param client DiscoveryClient
     * @param path 请求后缀路径
     * @param dept 请求的增量参数,在公司我使用的是List
     */
    public void refreshService(DiscoveryClient client, String path, Dept dept) {
    
    
        List<String> services = client.getServices();
        List<String> exceptServiceList = Arrays.asList("aoas", "ags", "asrc", "ascc", "asma");
        List<String> refreshServices = services.stream().filter(serviceId -> !exceptServiceList.contains(serviceId)).collect(Collectors.toList());
        for(String serviceId :refreshServices) {
    
    
            List<ServiceInstance> instances = client.getInstances(serviceId);
            //获取请求参数的url路径
            String url = "";
            for (ServiceInstance instance : instances) {
    
    
                // instance.getUri()+ 微服务模块路由前缀+path路径(每个公司不一样的)
                url = instance.getUri()+serviceId.split("-")[0].toLowerCase()+ path;
            }
            HttpHeaders headers = new HttpHeaders();
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            // 请求用户,这里作为mybatis plus的自动填充表的字段数据
            headers.add("UserId", "admin");
            // 机构信息
            headers.add("OrgId", "org");
            RestTemplate restTemplate = new RestTemplate();
            HttpEntity<String> formEntity = new HttpEntity<String>(JSON.toJSONString(dept), headers);
            // post请求调参数
            String s = restTemplate.postForObject(url, formEntity, String.class);
            System.out.println(s);
        }

    }
}

猜你喜欢

转载自blog.csdn.net/qq_39182939/article/details/113754644
今日推荐