已停止更新,源码及文档请进入https://github.com/huaPeiLiang/spring-cloud-start
一、回顾
上一篇文章:从零搭建spring cloud微服务二 · 客户端
上一篇文章介绍了Eureka客户端的搭建与注册,这一篇文章将会基于Eureka客户端的基础上搭建服务提供者与服务消费者。很多初学者会把这四个名词“Eureka服务端(注册中心)”、“Eureka客户端”、“服务提供者”、“服务消费者”搞混,包括我在刚接触微服务的时候也是如此,下面我会先介绍他们的区别。
文章结尾会有下期预览及下一篇文章链接,也可以直接访问:从零搭建spring cloud微服务系列导航
二、搭建服务端、客户端准备工作
下面就是一个简单的关系图。
首先“服务提供者”、“服务消费者”本质上来说就是Eureka客户端,他们都需要注册到注册中心,所以需要准备好两个Eureka客户端。
当用户请求服务消费者时,服务消费者通过Eureka注册中心发现服务提供者从而调用服务提供者的服务。下面会进行“服务提供者”、“服务消费者”的搭建以及讲解服务发现、调用的过程。
三、搭建服务提供者
在上面讲过服务提供者也是一个Eureka客户端,Eureka客户端搭建部分直接跳过(有疑问的请回顾上一篇文章)。
编写service:
package com.example.demo.service;
public interface OrderService {
String returnOrder();
}
编写service实现:
package com.example.demo.service.lmpl;
import com.example.demo.service.OrderService;
@Service
public class OrderServicelmpl implements OrderService {
public String returnOrder() {
return "hello你好1";
}
}
编写controller:
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.service.OrderService;
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping(value = "/order", method = RequestMethod.POST)
public String order() {
return orderService.returnOrder();
}
}
以上就是服务提供者的代码,下面到服务消费者。
方法一、通过RestTemplate发现与调用服务提供者
1、在服务提供者的配置文件中加上“eureka.instance.prefer-ip-address= true”允许通过注册在eureka上的名字发现他的访问路径。
2、在服务消费者的启动类中加上RestTemplate的Bean。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableEurekaClient
public class TenmakerCustomerApplication {
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(TenmakerCustomerApplication.class, args);
}
}
3、编写服务消费者的controller,通过服务提供者在Eureka注册中心注册的名字发现服务(注意:这里的“SERVICE-ORDER”是服务提供者在注册中心暴露出去的名称,如果你起的名字不同请自行修改)。
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class ConsumerController {
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/ribbon/consumer")
public String helloConsumer() {
String string = "1";
ResponseEntity<String> responseEntity = restTemplate.postForEntity("http://SERVICE-ORDER/order", string, String.class);
return responseEntity.getBody();
}
}
方法二、通过feign实现服务调用
1、在服务提供者的配置文件中加上“eureka.instance.prefer-ip-address= true”允许通过注册在eureka上的名字发现他的访问路径。
2、在服务消费者中添加feign依赖,做一个说明不同版本的cloud引入pom依赖可能不太一样,我使用的cloud版本是Greenwich.M3。想要了解openfeign原理的请点击:http://techblog.ppdai.com/2018/05/28/20180528/
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3、在服务消费者的主启动类中加入@EnableFeignClients注解。
4、在服务消费者中编写调用类,同样是通过注册在注册中心的名称来发现服务提供者。
package com.example.demo.api;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient("SERVICE-ORDER")
public interface OrderApi {
@RequestMapping(value = "/order" , method = RequestMethod.POST)
String returnOrder();
}
5、编写服务消费者的controller。
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.api.OrderApi;
@RestController
public class ConsumerController {
@Autowired
private OrderApi orderApi;
@RequestMapping(value = "/ribbon/consumer")
public String helloConsumer() {
return orderApi.returnOrder();
}
}
两者对比
以上两种调用方式都是基于http发出的请求。
方法一:优点:无需在服务消费者上编写调用类,结构清晰,易于理解。
缺点:调用较为复杂。
方法二:优点:调用简单,比较类似于单机应用的方法调用。
缺点:需要编写调用类,代码较冗余。
四、测试调用
访问服务消费的地址调用服务。依我为例,我给服务消费端配置的端口是80所以我直接访问“localhost/ribbon/consumer”。
五、下期预览
下期本来准备引入负载均衡的,但是基本模块还都没梳理完成。所以下期的文章会进行共用模块的搭建,之后进行配置中心搭建。负载均衡总会来的,敬请期待。