咱們在進行微服務項目的開發的時候,常常會遇到一個問題,好比A服務是一個針對用戶的服務,裏面有用戶的增刪改查的接口和方法,而如今我有一個針對產品的服務B服務中有一個查找用戶的需求,這個時候咱們能夠在B服務裏再寫一個查找用戶的接口,但是就爲了一個接口就得從控制層到持久層都寫一遍怎麼看都不值當,最關鍵的是這個接口在別的服務裏面還有,這就更不該該作了,因此springCloud提供了服務調用的方法——feign。java
因爲以前寫的都是springboot的例子,因此一直都只有一個服務,此次既然是服務調用,必然有一個服務提供者和消費者,若是要讓這兩個服務聯繫起來,就得用到springCloud的那一套東西,因此意味着咱們還得要一個服務註冊中心eureka,先把eureka註冊中心的代碼貼一下。web
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
相比以前的springboot啓動類,這裏多了一個@EnableEurekaServer註解,此註解的做用就是啓用一個服務註冊中心以提供給其餘服務進行對話。spring
配置文件application.propertiesapache
#服務註冊中心實例的主機名
eureka.instance.hostname=localhost
#是否向服務註冊中心註冊本身
eureka.client.register-with-eureka=false
#是否檢索服務
eureka.client.fetch-registry=false
#服務註冊中心的配置內容,指定服務註冊中心的位置
eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
#服務註冊中心端口號
server.port=8763
每一個配置項上面註釋都解釋了,其中第二個註解若是選擇true的話,在註冊中心啓動後便會存在一個服務即自己,但大部分狀況都是寫的faslejson
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.fh.msDemo</groupId> <artifactId>service-eureka</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
把以上三個文件在相應位置建好以後,把服務一塊兒輸入「主機名」+「端口」便可訪問註冊中心,按照我上面的配置輸入的是localhost:8763或者127.0.0.1:8763瀏覽器
效果以下:springboot
由於我默認了不註冊本身,因此目前沒有實例。app
好了,再來看一下兩個業務服務,首先是服務提供者用戶服務service-user,這裏爲了簡單起見,只在controller中模擬查詢的業務場景負載均衡
package com.fc.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class UserApplication{ public static void main(String[] args) { SpringApplication.run(UserApplication.class, args); } }
能夠看到和springboot項目不一樣的是這個服務多了一個註解@EnableEurekaClient,該註解的做用就是以eureka做爲服務註冊中心將服務註冊上去。框架
package com.fc.demo.controller; import java.util.ArrayList; import java.util.List; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.fc.demo.pojo.User; @RestController public class UserController { @RequestMapping("/user/list") public List<User> getUser() { List<User> users = new ArrayList<>(); users.add(new User(1, "小明", 13)); users.add(new User(2, "小華", 15)); return users; } }
#服務註冊中心的地址
eureka.client.service-url.defaultZone=http://localhost:8763/eureka/
#服務端口號
server.port=8768
#服務名稱
spring.application.name=user
最後是服務消費者產品服務service-product
package com.fc.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.feign.FeignClient;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ProductApplication{
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
與上一個服務相比,此服務又多了一個註解@EnableFeignClients,該註解的做用是:告訴框架掃描全部經過註解@Feignclient定義的feign客戶端,也就是說若是不加這個註解,框架將找不到全部的feign客戶端。
package com.fc.demo.feign; import java.util.List; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.cloud.netflix.feign.FeignClientsConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import com.fc.demo.pojo.User; @FeignClient(value="user",configuration = {FeignClientsConfiguration.class}) public interface UserFeign { @RequestMapping("/user/list") public List<User> getAllUser(); }
只要@FeignClient註解中的value值和服務提供者的服務名保持一致便可。
package com.fc.demo.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.fc.demo.feign.UserFeign; import com.fc.demo.pojo.User; @RestController public class ProductController { @Autowired private UserFeign userFeign; @RequestMapping("user/list") public List<User> showUser() { return userFeign.getAllUser(); } }
前面也提到了@EnableFeignClients註解將全部的feign客戶端注入了容器中,直接使用自動裝配的註解的即可使用feign客戶端
#服務註冊中心的地址
eureka.client.service-url.defaultZone=http://localhost:8763/eureka/
#服務端口號
server.port=8767
#服務名稱
spring.application.name=product
把三個服務同時跑起來,註冊中心截圖以下
顯示兩個服務已經註冊成功了。接下來在瀏覽器中輸入http://localhost:8767/user/list,成功返回json串
此外,feign還具備負載均衡的功能,修改user服務的controller,新增一個返回端口號的方法
package com.fc.demo.controller; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.fc.demo.pojo.User; @RestController public class UserController { @Value("${server.port}") private String port; //獲取配置文件中的端口號 /**獲取用戶列表*/ @RequestMapping("/user/list") public List<User> getUser() { List<User> users = new ArrayList<>(); users.add(new User(1, "小明", 13)); users.add(new User(2, "小華", 15)); return users; } /**獲取服務端口號*/ @RequestMapping("/user/port") public String getPort() { return port; } }
在product服務裏面的UserFeign接口和controller中增長相應的方法
package com.fc.demo.feign; import java.util.List; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.cloud.netflix.feign.FeignClientsConfiguration; import org.springframework.web.bind.annotation.RequestMapping; import com.fc.demo.pojo.User; @FeignClient(value="user",configuration = {FeignClientsConfiguration.class}) public interface UserFeign { /**獲取用戶列表*/ @RequestMapping("user/list") public List<User> getAllUser(); /**獲取服務端口號*/ @RequestMapping("user/port") public String getPort() ; }
package com.fc.demo.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.fc.demo.feign.UserFeign; import com.fc.demo.pojo.User; @RestController public class ProductController { @Autowired private UserFeign userFeign; /**獲取用戶列表*/ @RequestMapping("user/list") public List<User> showUser() { return userFeign.getAllUser(); } /**獲取服務端口號*/ @RequestMapping("/user/port") public String getPort() { return "調用的服務端口號爲"+userFeign.getPort(); } }
把服務跑起來之後,修改user服務配置文件中的端口號改成8769,再次跑一遍,這時eureka上顯示user服務有兩個實例,端口號分別爲8767和8769,屢次刷新瀏覽器
效果基本就是這樣,採用輪詢機制調用兩個user實例。
feign的基本用法就是這樣,目前本人對於springcloud和feign的瞭解也僅限於此,只知道基本的用法,對於其原理機制一律不知,因此還得繼續深究下去,如有收穫則會完善該系列後續的博客。