前面講了服務的註冊和發現,在微服務架構中,業務會被拆分成一個個的微服務,服務與服務又是如何通訊的?
SpringCloud中的通信協議是基於HTTP restful的,其中有兩種服務調用方式,一種是ribbon+restTemplate,另一種是feign。
ribbon
ribbon是一個負載均衡客戶端,可以很好的控制htt和tcp的一些行爲。Feign默認集成了ribbon。
1.依賴
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
2.配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8763
spring:
application:
name: service-ribbon
3.代碼
3.1 在工程的啓動類中,通過@EnableDiscoveryClient向服務中心註冊(如果使用eureka作爲註冊中心使用EnableEurekaClient,@EnableDiscoveryClient都可以,若使用consul等註冊中心方案需使用@EnableDiscoveryClient)
@SpringBootApplication
@EnableEurekaClient
//@EnableDiscoveryClient
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run( ServiceRibbonApplication.class, args );
}
}
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run( ServiceRibbonApplication.class, args );
}
}
3.2 @Bean向程序的ioc注入一個bean: restTemplate;並通過@LoadBalanced註解表明這個restRemplate開啓負載均衡的功能。
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
3.3 在SERVICE-HI服務中提供遠程方法
@RestController
public class HelloControler {
@GetMapping(value = "/hi")
public String hi(@RequestParam String name) {
return helloService.hiService( name );
}
}
3.4 注入RestTemplate模版,在service中編寫邏輯(遠程方法調用)調用SERVICE-HI的Controller中hi方法。
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
public String hiService(String name) {
return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
}
}
3.5 在service-ribbon服務中提供hello接口測試遠程調用SERVICE-HI服務方法。
@RestController
public class HelloControler {
@Autowired
HelloService helloService;
@GetMapping(value = "/hello")
public String hello(@RequestParam String name) {
return helloService.hiService( name );
}
}
如果SERVICE-HI服務,在註冊中心上註冊了多個實例,則多次調用時會交替調用服務實例,實現負載。
Feign
Feign是一個聲明式的僞Http客戶端,它使得寫Http客戶端變得更簡單。使用Feign,只需要創建一個接口並註解。Feign默認集成了Ribbon,和Eureka結合默認實現負載效果。
1.依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.配置文件
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8765
spring:
application:
name: service-feign
3.代碼
3.1 在程序的啓動類ServiceFeignApplication,加上@EnableFeignClients註解開啓Feign的功能
如果需要將所有feignAPI接口寫到maven的一個子工程裏,@EnableFeignClients註解需要指明路徑@EnableFeignClients(“com.api.feign”)
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ServiceFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceFeignApplication.class, args);
}
}
3.2 編寫一個controller提供hello接口供外部調用
@RestController
public class HiController {
@Autowired
SchedualServiceHi schedualServiceHi;
@RequestMapping(value = "/hello",method = RequestMethod.GET)
public String sayHi(@RequestParam String name){
return schedualServiceHi.sayHiFromClientOne(name);
}
}
同ribbon,如果服務提供方開啓多個實例,會使用負載依次調用其服務。
本文參考文章:方誌鵬-深入理解SpringCloud與微服務構建