spring cloud 10 feign

一、服務調用
服務調用和消息一般是兩個維度初婆,
1,服務調用是同步的
2猿棉,消息是異步的回調磅叛,事件的一個周期

二、準備
? 遠程過程調用(RPC)

? 接口定義語言(IDL)
interface definition language

? 通訊協(xié)議(Protocol)
HTTP萨赁,web-socket弊琴,Socket

? Netflix Feign
契約式編程
springcloud將Feign和spring mvc整合

? Spring Cloud 技術回顧 (服務短路 、負載均衡杖爽、服務發(fā)現(xiàn)访雪、分布式配置等)

image.png

三、
1掂林,NOSQL:redis,elasticsearch,mongodb
2臣缀,integration:rabbitmq,kafka,
3,config:config client/config server/zookeeper config/consul config
4泻帮,discovery:eureka server,eureka discovery,zookeeper discovery,consul discovery
5精置,routing:zuul,gateway,ribbon,feign
6,circuit breaker:hystrix,turbine

四、核心概念
1锣杂,遠程過程調用(RPC)
remote procedure call脂倦,通過網(wǎng)絡進行傳輸。
一個計算機通信協(xié)議元莫。該協(xié)議允許運行于一臺計算機的程序調用另一臺計算機的子程序(進程)赖阻,而程序員無需額外地為這個交互作用編程。如果涉及的軟件采用面向對象編程踱蠢,那么遠程過程調用亦可稱作遠程調用或遠程方法調用火欧。
? 例如
? Java RMI(二進制協(xié)議)進程之間的協(xié)議棋电,必須用POJO(序列化&反序列化)
? WebServices(文本協(xié)議)一般都有骨架或者說是結構,比如XML schema

2苇侵,消息傳遞
RPC 是一種請求-響應協(xié)議赶盔,一次 RPC在客戶端初始化,再由客戶端將請求消息傳遞到遠程的服務器榆浓,執(zhí)行指定的帶有參數(shù)(這里的參數(shù)和方法的參數(shù)有所區(qū)別于未。這里的參數(shù)也有可能是請求頭之類的信息)的過程。經(jīng)過遠程服務器執(zhí)行過程后陡鹃,將結果作為響應內容(響應頭和響應體)返回到客戶端烘浦。

3,存根(Stub)
在一次分布式計算 RPC 中萍鲸,客戶端和服務器轉化參數(shù)(不僅僅是方法的參數(shù))的一段代碼谎倔。 由于存根的參數(shù)轉化,RPC執(zhí)行過程如同本地執(zhí)行函數(shù)調用猿推。存根必須在客戶端和服務器兩端均裝載片习,并且保持兼容(比如高版本的服務端兼容低版本的客戶端調用)。

HTTP調用的存根在于內部的實現(xiàn)蹬叭。web服務器和客戶端都支持HTTP協(xié)議的話藕咏,那么協(xié)議的內容和格式就是存根。
如果是java rmi(remote method invoke)的話秽五,兩邊都必須要有接口孽查,傳輸?shù)哪P蛯ο蟊仨毿蛄谢惖陌姹疽3忠恢绿勾琾ojo的字段也要兼容盲再。
java 序列化主要關注POJO字段的狀態(tài),對pojo的方法不是很關注瓣铣。

五答朋、spring cloud feign
? 依賴
? org.springframework.cloud:spring-cloud-starter-feign
? 激活
? @EnableFeignClients (標記在服務調用方的SpringApplication上)
? 申明
? @FeignClient 標記在接口Api上,name="服務提供方的service id"

申明@FeignClient API棠笑,name屬性盡量使用占位符梦碗,避免硬編碼。

package com.xixi.spring.cloud8.server.api;

import com.xixi.spring.cloud8.server.domain.User;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * 用戶服務
 * 聲明Feign客戶端,feigncliet里面的方法將會映射到rest api
 * ${user-service-name}指向user-service-provider
 */
@FeignClient(name = "${user-service-name}")//利用占位符蓖救,避免未來整合硬編碼
public interface UserService {

    /**
     * 保存用戶
     * @param user
     * @return
     */
    @PostMapping("/user/save")
    boolean saveUser(@RequestBody User user);


    /**
     * 查詢所有的用戶列表
     * @return
     */
    @GetMapping("/user/list")
    List<User> findAll();
}

在user-service-client客戶端激活@EnableFeignClients洪规,放在服務調用方上,申明要激活的接口循捺。在這里是UserService.class

@EnableFeignClients(clients = {UserService.class})
public class UserServiceClientApplication{}

六斩例、默認組件
? Decoder/Encoder : ResponseEntityDecoder / SpringEncoder
? Logger : Slf4jLogger
? Contract : SpringMvcContract
原生的feign并不支持我們spring mvc的annotation(@RequestMapping),但是和spring結合以后就支持了从橘,靠SpringMvcContract
如果想自己擴展念赶,可以實現(xiàn)Contract础钠,Contract的作用就是Define what annotations and values are valid on interfaces.
? Feign.Builder : HystrixFeign.Builder
? Client : LoadBalancerFeignClient( Ribbon 激活的話)

feign的底層還是ribbon LoadBalancerClient那一套,

七晶乔、? 整合負載均衡: Netflix Ribbon

1,user-service-client的配置文件application.properties

###ribbon 客戶端應用
spring.application.name = user-ribbon-client

eureka.client.enabled = false
##服務提供方名稱
provider.service.name = user-service-provider
##服務提供方主機
provider.service.host = localhost
###服務提供方端口
provider.service.port = 8081
server.port = 8080


##關閉eureka注冊,通過顯示地配置服務端的地址
##定義服務提供方地址,為RibbonLoadBalancerClient提供服務列表牺勾,如果有多個可以用逗號隔開正罢。
user-service-provider.ribbon.listOfServers = \
  http://${provider.service.host}:${provider.service.port}

##配置自定義實現(xiàn)的MyPing,這樣就不用@Bean去配置IPing,
# user-service-provider是要被負載均衡的服務
user-service-provider.ribbon.NFLoadBalancerPingClassName=\
  com.xixi.spring.cloud8.server.user.ribbon.client.ping.MyPing

###配置@FeignClient(name = "${user.service.name}")中的占位符
#user.service.name需要制定user service接口的提供方,也就是user-service-provider
user.service.name = ${provider.service.name}

2驻民,服務調用方激活@EnableFeignClients翻具,使用user-service調用服務
在UserRibbonController中注入userServiceFeignClient

  /**
   * 同一個接口不建議在客戶端和服務端之間共享,實際情況最好使用組合UserService的方式
   * FeignClient標記的接口可以直接注入,F(xiàn)eign會動態(tài)代理幫我們去構造它的實現(xiàn)類
   */
  @Autowired
  private UserService userServiceFeignClient;

  @GetMapping("/user/list")
  public List<User> getUserList2() {

    return userServiceFeignClient.findAll();
  }

3回还,服務端實現(xiàn)user-service API裆泳,暴露Rest接口
首先,

@Service("inMemoryUserService")
public class InMemoryUserService implements UserService

其次柠硕,
user-service-provider是最終的服務提供方工禾,不需要標記為feignClient
UserServiceProviderController implements UserService
UserServiceProviderController實現(xiàn)feignclient接口。

最后蝗柔,

  //由于UserServiceProviderController繼承了UserService闻葵,所以這塊可以不寫@PostMapping("/user/save")。Feign Inheritance Support
  //注意:@PostMapping會被繼承癣丧,但是@RequestBody槽畔,@RequestParam是不會被繼承的,method parameter mapping is not inherited
  //這是因為java語言的特性決定的胁编,方法外面的東西可以從父類繼承厢钧,但是方法里面的實現(xiàn),子類會覆蓋父類嬉橙。
  //URL映射可以從父類繼承早直。PostMapping("/user/save")
  @Override
  public boolean saveUser(@RequestBody User user) {
    return userService.saveUser(user);
  }

八、? 整合服務短路: Netflix Hystrix
1市框,調整UserService api

package com.xixi.spring.cloud10.server.api;

import com.xixi.spring.cloud10.server.domain.User;

import com.xixi.spring.cloud10.server.fallback.UserServiceFallback;
import java.util.List;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

/**被標記為@FeignClient的接口莽鸿,將會偽裝UserService的客戶端去調用它要調用的服務
 * 用戶服務
 * 聲明Feign客戶端,feign client里面的方法將會映射到rest api
 * ${user-service-name}指向user-service-provider
 *
 * 整合Hystrix Fallback
 */
@FeignClient(name = "${user.service.name}",//利用占位符,避免未來整合硬編碼
    primary = true,//primary = true表示當UserService有多個實現(xiàn)類的時候拾给,F(xiàn)eignClient動態(tài)代理的那個實現(xiàn)類優(yōu)先級最高
    fallback = UserServiceFallback.class )
public interface UserService {

    /**
     * 保存用戶
     * @param user
     * @return
     */
    @PostMapping("/user/save")
    boolean saveUser(@RequestBody User user);


    /**
     * 查詢所有的用戶列表
     * @return
     */
    @GetMapping("/user/list")
    List<User> findAll();
}


寫一個UserServiceFallback

package com.xixi.spring.cloud10.server.fallback;

import com.xixi.spring.cloud10.server.api.UserService;
import com.xixi.spring.cloud10.server.domain.User;
import java.util.Collections;
import java.util.List;

public class UserServiceFallback implements UserService {

  @Override
  public boolean saveUser(User user) {
    return false;
  }

  @Override
  public List<User> findAll() {
    return Collections.emptyList();
  }
}

2祥得,在user-service-provider上整合@HystrixCommand

  @HystrixCommand(commandProperties = {
      //設置超時時間為100ms
      @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "100")
  },
      //通過@HystrixCommand#fallbackMethod()實現(xiàn)異常處理,設置fallback方法,會在當前類或是他的父類里面去找fallbackForGetUsers()
      fallbackMethod = "fallbackForGetUsers")
  public List<User> findAll() {
    return userService.findAll();
  }

九、? 整合服務發(fā)現(xiàn): Netflix Eureka
(廢棄ribbon白名單配置的方式蒋得,使用eureka獲取服務列表)
1级及,寫一個eureka-server
(1)引入eureka-server jar
(2)寫引導類
(3)配置文件application.properties
2,user-service-client增加服務發(fā)現(xiàn)配置
(1)加依賴

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

(2)引導類激活服務發(fā)現(xiàn)@EnableDiscoveryClient
(3)application.properties,注意要注釋掉之前白名單的配置

eureka.client.enabled = true
###連接eureka server
eureka.server.hostname = localhost
eureka.server.port = 8083
eureka.client.serviceUrl.defaultZone = \
  http://${eureka.server.hostname}:${eureka.server.port}/eureka

3额衙,user-service-provider增加服務發(fā)現(xiàn)配置
(1)加依賴
(2)引導類加注解@EnableDiscoveryClient
(3)application.properties

十饮焦、? 整合配置服務器: Config Server
(1)加依賴

    s<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-config-server</artifactId>
    </dependency>

(2)引導類加注解@EnableDiscoveryClient,@SpringBootApplication,@EnableConfigServer
(3)application.properties

1,配置user-service.properties

###user-service-client配置內容怕吴,作為user-service-client配置內容的一部分,
# user-service-client本身也會有自己的application.properties
##如果有沖突县踢,user-service的配置內容優(yōu)先
##服務提供方名稱
provider.service.name = user-service-provider
##服務提供方主機
#provider.service.host = localhost
####服務提供方端口
#provider.service.port = 8081

###配置@FeignClient(name = "${user.service.name}")中的占位符
#user.service.name需要制定user service接口的提供方转绷,也就是user-service-provider
user.service.name = ${provider.service.name}

2,

3,

十一、? 整合配置客戶端: Config Client

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末硼啤,一起剝皮案震驚了整個濱河市议经,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谴返,老刑警劉巖煞肾,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嗓袱,居然都是意外死亡籍救,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門渠抹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝙昙,“玉大人,你說我怎么就攤上這事梧却∷屎冢” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵篮幢,是天一觀的道長大刊。 經(jīng)常有香客問我,道長三椿,這世上最難降的妖魔是什么缺菌? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮搜锰,結果婚禮上伴郁,老公的妹妹穿的比我還像新娘。我一直安慰自己蛋叼,他們只是感情好焊傅,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著狈涮,像睡著了一般狐胎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上歌馍,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天握巢,我揣著相機與錄音,去河邊找鬼松却。 笑死暴浦,一個胖子當著我的面吹牛溅话,可吹牛的內容都是我干的。 我是一名探鬼主播歌焦,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼飞几,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了独撇?” 一聲冷哼從身側響起屑墨,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎券勺,沒想到半個月后绪钥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灿里,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡关炼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了匣吊。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片儒拂。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖色鸳,靈堂內的尸體忽然破棺而出社痛,到底是詐尸還是另有隱情,我是刑警寧澤命雀,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布蒜哀,位于F島的核電站,受9級特大地震影響吏砂,放射性物質發(fā)生泄漏撵儿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一狐血、第九天 我趴在偏房一處隱蔽的房頂上張望淀歇。 院中可真熱鬧,春花似錦匈织、人聲如沸浪默。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纳决。三九已至,卻和暖如春乡小,著一層夾襖步出監(jiān)牢的瞬間岳链,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工劲件, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留掸哑,地道東北人约急。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像苗分,于是被迫代替她去往敵國和親厌蔽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內容