建立5個項目:java
1.服務註冊中心git
2.服務提供者1github
3.服務提供者2(與服務提供者1的代碼實現同樣,這是是爲了模擬負載均衡)web
4.ribbon客戶端項目spring
5.feign客戶端項目瀏覽器
如圖:springboot
1、註冊中心項目:app
pom文件中添加:負載均衡
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency>
啓動類:ide
/** * MainApp類描述: 服務註冊中心 * * @author yangzhenlong * @since 2017/3/16 */ @EnableEurekaServer//註解啓動一個服務註冊中心 @SpringBootApplication public class RegisterMainApp { public static void main(String[] args) { SpringApplication.run(RegisterMainApp.class, args); } }
application配置文件:
server.port=8888 #在默認設置下,該服務註冊中心也會將本身做爲客戶端來嘗試註冊它本身,因此咱們須要禁用它的客戶端註冊行爲 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false #服務註冊地址 eureka.instance.ip-address=localhost eureka.instance.prefer-ip-address=true eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
而後啓動項目,訪問:http://localhost:8888/
這時候發現,Application下面是空的,由於尚未服務註冊進來
2.服務提供1
pom文件:
啓動類:
/** * MainApp類描述: 服務提供 * * @author yangzhenlong * @since 2017/3/16 */ @EnableDiscoveryClient//激活Eureka中的DiscoveryClient實現 @SpringBootApplication public class ProviderMainApp { public static void main(String[] args) { SpringApplication.run(ProviderMainApp.class, args); } }
提供的rest接口類:
1 package com.eureka.rest; 2 3 4 import org.slf4j.Logger; 5 import org.slf4j.LoggerFactory; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.cloud.client.ServiceInstance; 8 import org.springframework.cloud.client.discovery.DiscoveryClient; 9 import org.springframework.web.bind.annotation.PathVariable; 10 import org.springframework.web.bind.annotation.RequestMapping; 11 import org.springframework.web.bind.annotation.RestController; 12 13 import java.util.List; 14 15 /** 16 * UserController類描述: 17 * 18 * @author yangzhenlong 19 * @since 2017/4/13 20 */ 21 @RestController() 22 public class UserController { 23 24 private final static Logger LOGGER = LoggerFactory.getLogger(UserController.class); 25 @Autowired 26 private DiscoveryClient discoveryClient; 27 28 @RequestMapping("/") 29 public String index(){ 30 return "index"; 31 } 32 33 @RequestMapping("/client") 34 public String client(){ 35 String description = discoveryClient.description(); 36 ServiceInstance localServiceInstance = discoveryClient.getLocalServiceInstance(); 37 List<String> services = discoveryClient.getServices(); 38 StringBuffer sb = new StringBuffer(); 39 sb.append("discoveryClient描述:" + description); 40 sb.append("\ndiscoveryClient本地服務HOST:" + localServiceInstance.getHost() + "---port:" + localServiceInstance.getPort() + "---serverId:" +localServiceInstance.getServiceId()); 41 sb.append("\ndiscoveryClient services:" + services); 42 return "discoveryClient:" + sb.toString(); 43 } 44 45 @RequestMapping("/{id}") 46 public String get(@PathVariable String id){ 47 logCurrServerInfo(); 48 return discoveryClient.getLocalServiceInstance().getHost() 49 + discoveryClient.getLocalServiceInstance().getPort() 50 + "<hr/>用戶:" + id; 51 } 52 53 @RequestMapping("/add/{name}") 54 public String add(@PathVariable String name){ 55 logCurrServerInfo(); 56 return discoveryClient.getLocalServiceInstance().getHost() 57 + discoveryClient.getLocalServiceInstance().getPort() 58 + "<hr/>添加用戶:" + name; 59 } 60 61 @RequestMapping("/getAll") 62 public String add(){ 63 logCurrServerInfo(); 64 String s = ""; 65 for(int i=1; i<=5; i++){ 66 s = s + i + "測試測試" + System.currentTimeMillis() + "\n"; 67 } 68 return discoveryClient.getLocalServiceInstance().getHost() 69 + discoveryClient.getLocalServiceInstance().getPort() 70 + "<hr/>全部用戶:" + s; 71 } 72 private void logCurrServerInfo(){ 73 LOGGER.info("當前服務信息------\n ServiceId:{}, \n Host:{},\n Port:{}", 74 discoveryClient.getLocalServiceInstance().getServiceId(), 75 discoveryClient.getLocalServiceInstance().getHost(), 76 discoveryClient.getLocalServiceInstance().getPort() 77 ); 78 } 79 80 }
application配置:
server.port=1111 server.address=localhost spring.application.name=provider #註冊中心地址 eureka.instance.ip-address=localhost eureka.instance.prefer-ip-address=true eureka.client.serviceUrl.defaultZone=http://localhost:8888/eureka/
而後啓動該項目,這時候看見註冊中心console打印信息:有服務爲provider端口爲1111的服務註冊進來了
再刷新http://localhost:8888/註冊中心頁面,發現application中有註冊進來一個服務,名稱爲PROVIDER
這樣第一個服務就註冊完成了
3.服務提供者2(這裏爲了模仿負載均衡,provider1項目的代碼拷貝一份,修改端口爲2222),和第二步相似,只是配置文件中,設置端口爲:2222
啓動服務,查看註冊服務console:
刷新註冊中心地址,發現2個服務註冊到同一個服務名稱,只是端口不同
4.ribbon http客戶端
pom文件中加入eureka和ribbon:
<!--父依賴包-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
<relativePath/>
</parent>
<!--eureka-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!--ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
注:這裏的springboot版本要設置爲1.3.x,若是設置1.4.x,啓動項目的時候,會報錯:
springboot版本選擇1.4.x時會報錯:
org.springframework.core.annotation.AnnotationConfigurationException: Attribute 'value' in annotation [org.springframework.cloud.netflix.feign.FeignClient] must be declared as an @AliasFor [serviceId], not [name].
啓動類:
@EnableDiscoveryClient//發現服務 @SpringBootApplication public class ClientRibbonMainApp { @Bean @LoadBalanced//開啓均衡負載能力 public RestTemplate restTemplate(){ return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(ClientRibbonMainApp.class, args); } }
http客戶端調用:
@RestController() public class RibbonController { private final static Logger LOGGER = LoggerFactory.getLogger(RibbonController.class); @Autowired private RestTemplate restTemplate; @RequestMapping("/") public String index(){ return "index"; } @RequestMapping("/add/{name}") public String add(@PathVariable String name){ ResponseEntity<String> forEntity = restTemplate.getForEntity("http://PROVIDER/add/" + name, String.class); return forEntity.getBody(); } }
啓動ClientRibbonMainApp類後,註冊服務:
這時候去訪問ribbon項目:http://localhost:1234/add/12djsf
再去查看2臺服務提供者項目的控制檯console:
發現Provider2被調用了,到瀏覽器屢次請求http://localhost:1234/add/12djsf,發現有時候會調用服務1,有時候會調用服務2,因此這裏咱們的負載均衡起做用了。
ribbon客戶端就完成了。。
5.feigh http客戶端
首先pom中添加eureka和feign的依賴:
<!--eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> <!--feign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency>
啓動類:
@EnableDiscoveryClient//發現服務 @EnableFeignClients//開啓Feign功能 @SpringBootApplication public class ClientFeignMainApp { public static void main(String[] args) { SpringApplication.run(ClientFeignMainApp.class, args); } }
註冊服務端的類,這裏使用接口註解的方式,實現rpc調用:
@FeignClient("provider")//註冊中心註冊的服務名稱,也就是serviceId public interface ProviderFeignClient { @RequestMapping("/add/{name}") String add(@RequestParam(value = "name") String name); @RequestMapping("/getAll") String getAll(); }
調用服務:把服務接口注入進來,直接使用接口中的方法實現rpc
@RestController public class FeignController { private final static Logger LOGGER = LoggerFactory.getLogger(FeignController.class); @Autowired private ProviderFeignClient providerFeignClient; @RequestMapping("/feign") public String index(){ String all = providerFeignClient.getAll(); return "------" + all; } }
啓動ClientFeignMainApp類
瀏覽器訪問:http://localhost:1233/feign
發現有時候調用服務1,有時候調用服務2,這裏用feign也能實現http負載均衡。