SpringCloudAlibaba基础教程:支持的几种服务消费方式(ResTemplate,webClient,Feign)

通过《Spring Cloud Alibabad基础教程:使用Nacos实现服务注册与发现》一文的学习,我们已经学会了如何使用Nacos来实现服务注册与发现,同时有介绍如何通过LoadBalancerClent接口来获取某个服务的具体实例,并根据实例西信息来发起服务接口消费请求。但是这样的做法需要我们手工去编写服务选取。连接拼接等繁琐的工作,对于开发人员来说非常不友好。所以接下来,我们看看除此之外,还支持那些其他服务消费方式

使用RestTemplate

在之前的例子中,已经使用过TestTmplate来向服务的某个具体实例发起HTTP请求,但是具体的请求路径是通过拼接完成的,对于开发体验并不好。但是,实际上,SpringCloud对RestTemplate做了增强,只需要稍加配置,就能简化之前的调用方式。
比如


@EnableDiscoveryClient
@SpringBootApplication
public class AlibabaNacosDiscoveryClientCommonApplication {
    public static void main(String[] args) {
        SpringApplication.run(AlibabaNacosDiscoveryClientCommonApplication.class, args);
    }

    @Slf4j
    @RestController
    static class TestController {

        @Autowired
        LoadBalancerClient loadBalancerClient;
        @Autowired
        RestTemplate restTemplate;
        
        @GetMapping("test")
        public String test() {
            ServiceInstance serviceInstance = loadBalancerClient.choose("alibaba-nacos-discovery-server");
            String url = serviceInstance.getUri() + "?name=" + "juzhi";
            RestTemplate restTemplate = new RestTemplate();
            String result = restTemplate.getForObject(url, String.class);
            return "Invoke:" + url + ",return:" + result;
        }

        @GetMapping("testRestTemplateBatter")
        public String testRestTemplateBatter() {
            String result=restTemplate.getForObject("http://alibaba-nacos-discovery-server?name=orange",String.class);
            return result;
        }
        
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
			return new RestTemplate();
        }
    }
}

可以看到,在RestTemplate的时候,增加了@LoadBalanced注解,而在真正调用服务接口的时候,原来hos部分手工拼接ip和端口的,直接采用服务名的来请求路径即可。而真正调用的时候,SpringCloud 会将亲贵拦截下来,然后通过负载均衡选出节点,并替换服务名部分为具体的ip和端口,从而实现基于服务名的负载均衡调用。

使用WebClient

webClient是Spring 5中最新引入的,可以将其理解为reactive版的RestTemplate.下面举个具体离职,它将实现与上面RestTemplate一样的请求调用
编辑pom.xml

	<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-webflux</artifactId>
		</dependency>

编辑代码

@EnableDiscoveryClient
@SpringBootApplication
public class AlibabaNacosDiscoveryClientCommonApplication {
    public static void main(String[] args) {
        SpringApplication.run(AlibabaNacosDiscoveryClientCommonApplication.class, args);
    }

    @Slf4j
    @RestController
    static class TestController {
        @Autowired
        LoadBalancerClient loadBalancerClient;
        @Autowired
        RestTemplate restTemplate;
        @Autowired
        private WebClient.Builder webClientBuilder;
        @GetMapping("test")
        public String test() {
            ServiceInstance serviceInstance = loadBalancerClient.choose("alibaba-nacos-discovery-server");
            String url = serviceInstance.getUri() + "?name=" + "juzhi";
            RestTemplate restTemplate = new RestTemplate();
            String result = restTemplate.getForObject(url, String.class);
            return "Invoke:" + url + ",return:" + result;
        }

        @GetMapping("testRestTemplateBatter")
        public String testRestTemplateBatter() {
            String result=restTemplate.getForObject("http://alibaba-nacos-discovery-server?name=orange",String.class);
            return result;
        }

        @GetMapping("testWebClient")
        public Mono<String> testWebClient(){
            Mono<String> result=webClientBuilder.build()
                    .get()
                    .uri("http://alibaba-nacos-discovery-server/?name=orangeWebClent")
                    .retrieve()
                    .bodyToMono(String.class);
            return result;
        }
        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
			return new RestTemplate();
        }

        @Bean
        @LoadBalanced
        public WebClient.Builder loadBalancedWebClientBuilder() {
            return WebClient.builder();
        }
    }
}

使用Feign

上面介绍的RestTemplate和WebClient都是Spring自己封装的工具,下面介绍一个Nettflixd OSS中的成员,通过它可以更方便定义和使用服务消费客户端。下面举个例子

第一步:在pom.xml中添加openfeign的依赖

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-openfeign</artifactId>
			<version>2.1.1.RELEASE</version>
		</dependency>

第二步:定义Fegin客户端和使用Feign客户端

@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class AlibabaNacosDiscoveryClientCommonApplication {
    public static void main(String[] args) {
        SpringApplication.run(AlibabaNacosDiscoveryClientCommonApplication.class, args);
    }

    @Slf4j
    @RestController
    static class TestController {
        @Autowired
        LoadBalancerClient loadBalancerClient;
        @Autowired
        RestTemplate restTemplate;
        @Autowired
        private WebClient.Builder webClientBuilder;
        @Autowired
        Client client;

        @GetMapping("test")
        public String test() {
            ServiceInstance serviceInstance = loadBalancerClient.choose("alibaba-nacos-discovery-server");
            String url = serviceInstance.getUri() + "?name=" + "juzhi";
            RestTemplate restTemplate = new RestTemplate();
            String result = restTemplate.getForObject(url, String.class);
            return "Invoke:" + url + ",return:" + result;
        }

        @GetMapping("testRestTemplateBatter")
        public String testRestTemplateBatter() {
            String result = restTemplate.getForObject("http://alibaba-nacos-discovery-server?name=orange", String.class);
            return result;
        }

        @GetMapping("testWebClient")
        public Mono<String> testWebClient() {
            Mono<String> result = webClientBuilder.build()
                    .get()
                    .uri("http://alibaba-nacos-discovery-server/?name=orangeWebClent")
                    .retrieve()
                    .bodyToMono(String.class);
            return result;
        }


        @GetMapping("testFeign")
        public String testFeign() {
            String result = client.hello("orangeFeign");
            return "Return:" + result;
        }


        @Bean
        @LoadBalanced
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }

        @Bean
        @LoadBalanced
        public WebClient.Builder loadBalancedWebClientBuilder() {
            return WebClient.builder();
        }

    }

    @FeignClient("alibaba-nacos-discovery-server")
    interface Client {
        @GetMapping("/")
        String hello(@RequestParam(name = "name") String name);
    }

}

这里主要先通过@EnableFeginClients 注解开启扫描SpringCloud Feign 客户端的功能,然后又创建一个Feign的客户端定义接口。使用@FeignClient注解来指定这个接口所要调用服务名称,接口中定义的各个函数使用SpringMVC的注解就可以来绑定服务提供方的REST接口,比如上面就是绑定alibaba-nacos-discovery-server服务的/接口的例子。最后,在Controller中,注入了client接口的实现,并调用hello方法来触发对服务提供方的调用。

深入思考

如果之前已经使用过Spring Cloud的读者,肯定会这样感受:不论我使用的RestTemplate也好,还是使用WebClient,还是使用Feign,似乎和我用不用Nacos没啥关系?我们在之前介绍Eureka和Consul的时候,也都是用看这样的方式来实现服务调用的。
不是吗?
确实如此,对于SpringCloud老手来说,就算我们更换了Nacos作为新的服务注册中心,其实对对于我们应用层面的代码是没有影响的。那为什么SpringCloud可以带给我们这样的完美体验呢,实际上,这完全归功与Spring Cloud Common的封装,由于服务注册与发现,客户端负载均衡等方面都做了很好的抽象,而上层应用方面依赖的都是这些抽象接口,而非针对某个具体中间件的实现。所以,在Spring Cloud中,我们可以很方便的去切换服务治理方面的中间件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值