springcloud 入門筆記-1
1.安裝sts(spring tool suite)
<!-- 熱部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
部署後項目前有[devtools],修改無需重啟
3.boot封裝了json,返回的物件都是json格式
2.依賴和整合
3.自定義封裝
可以是重複的類,也可是重複的feign介面
4.ribbon預設的負載均衡策略
預設是輪詢測略,可自定義為隨機策略
microservice-provider: ##config ribbon
ribbon:
eureka:
enabled: false
listOfServers: localhost:8000, localhost:8002,localhost:8003 #假設provider有3臺instance埠分別是8000 8002 8003
ServerListRefreshInterval : 15000 #設定服務列表重新整理時間間隔
注意:
1.自定義配時,@Configuration包和@ComponentsScan包不應重疊
2.使用RestTemplate時,想要獲得一個List時,應使用陣列,而不應該直接使用List
5.feign集成了ribbon和hystrix
1.feign是webservice的客戶端,
2.預設@FeignClient(name=”“)不寫預設為name,
不建議用service-id,看原始碼知過時了,
@Deprecated String serviceId() default ""
;其中引數還有個屬性為url,注意有url時必須有name
最重要的話: (官文原話)
– springcloud根據需要使用FeignClientConfiguration為每個命名的客戶端建立一個新的整體作為ApplicationContext.包含feign Decoder,feign Encoder,feign Contract
– 即@FeignClient(“”)建立了一個子容器 ,包含日誌,解碼器,編碼器,契約(是springmvcContract,故可以支援mvc註解)
3.有6個坑:
3.1.介面中的方法必須用@RequestMapping(value= method=…),不能使用@GetMaping(不支援),否則無法啟動
3.2.介面中的方法中往往有引數,一定不能省了@PathVariable(“”)設定value,否則報引數為0
3.3.介面中的方法中引數如果是物件,只能設定為Post方法,設定為get方法報錯:需要get方法,即使你設定的就是get.
如果一定要用get,只能將物件屬性全設定為引數,使用@RequestParam(“id”) int id,@RequestParam(“name”) string name…
3.4.在controller類中的註解上,如果不使用thymeleaf,則可用@RestController,對應方法上使用@GetMapping、@PostMapping;
如果使用thymeleaf,必須用@Controller,對應@RequestMaping…否則返回無法跳轉到頁面,只會返回物件
3.5.使用@Configuration時不要同時註解@ComponentsScan,有衝突
3.6 .啟動應用報timeout錯誤時配置:
解決第一次請求報錯超市異常(ms) hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 或者 hystrix.command.default.execution.timout.enabled: false
6.自定義feign
使用@FeignClient的configuration屬性,指定feign的配置類:
@FeignClient(name = "microservice-provider-user", configuration = FeignConfiguration.class) public interface UserFeignClient { /** * 使用feign自帶的註解@RequestLine * @see https://github.com/OpenFeign/feign * @param id 使用者id * @return 使用者資訊 */ @RequestLine("GET /{id}") public User findById(@Param("id") Long id); }
注意其中的註解格式,然後是配置類:
/** * 該類為Feign的配置類 * 注意:該不應該在主應用程式上下文的@ComponentScan中。 */ @Configuration public class FeignConfiguration { /** * 將契約改為feign原生的預設契約。這樣就可以使用feign自帶的註解了。 * @return 預設的feign契約 */ @Bean public Contract feignContract() { return new feign.Contract.Default(); } }
目錄結構為:
上面的方式只是為UserFeignClient 介面設定了feign的配置類,如果還有其他的介面怎麼辦?
目前的方法是建立第二個介面類,對應設定第二個配置類。
feign的功能很多:
1.壓縮GZIP:
feign.compression.request.enabled=true
feign.compression.response.enabled=true
2.日誌: yml中配置,使用介面類全類名:
logging: level: com.xx.UserFeignClient: DEBUG
同時在配置類中新增,四個級別NONE,BASIC,HEADERS,FULL
@Configuration public class FooConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
7.eureka常見問題
7.1 eureka介面的enviroment和datacenter配置
eureka: enviroment: product #eureka中環境 datacenter: cloud #eureka中datacenter,使用cloud,這樣eureka將會知道是在AWS雲上
7.2 eureka的自我保護提示
eureka的自我保護模式主要用於在一組客戶端和eureka伺服器之間存在網路分割槽的情況下的保護,在這些情況下,伺服器嘗試保護其已有的資訊。就是說即使某個服務停止了,註冊中心依然不剔除它。但是在開發階段,這個不是我們需要的。
注意的是使用sts,則保護模式會失效,因為在點選停止的時候,sts會呼叫springboot的shundown hook,這個鉤子會向eureka server主動下線。
如果要配置關閉自我保護,如下:
server端: eureka.server.enable-self-preservation #設為false,關閉自我保護模式 eureka.server.eviction-interval-timer-in-ms #清理間隔(ms,預設60*1000) client端: eureka.client.healthcheck.enabled = true #開啟健康檢查(actuator) eureka.instance.lease-renewal-interval-in-seconds=10 #租期更新時間間隔(預設30s) eureka.instance.lease-expiration-duration-in-seconds =30 #租期到期時間(預設90s)
示例如下:
eureka: instance: ip-address: 172.x.x.x prefer-ip-address: true lease-renewal-interval-in-seconds: 10 # 租期更新時間間隔(預設30s) lease-expiration-duration-in-seconds: 30 #租期到期時間(預設90s) client: serviceUrl: defaultZone: http://172.x.x.x:9079/eureka/ register-with-eureka: true fetch-registry: true healthcheck: enabled: true #開啟健康檢查(actuator) server: enable-self-preservation: false #設為false,關閉自我保護模式 eviction-interval-timer-in-ms: 4000 #清理間隔(ms,預設60*1000)
注意
1.更改eureka更新頻率將打破伺服器的自我保護功能
2.生產階段不要更改eureka的配置,否則保護模式失效
8.feign的hystrix支援
Hystrix支援回退的概念:當斷路器開啟或者出現錯誤時執行的預設程式碼路徑,要為給定的@FeignClient啟用回退,請將fallback屬性設定為實現回退的類名。
全域性開啟或禁用hystrix:
feign.hystrix.enabled = false
前面提到feign下整合有ribbon和hystrix,已經整合,只需要在feign中配置fallback即可
/** * Feign的fallback測試 * 使用@FeignClient的fallback屬性指定回退類 */ @FeignClient(name = "microservice-provider-user", fallback = FeignClientFallback.class) public interface UserFeignClient { @RequestMapping(value = "/{id}", method = RequestMethod.GET) public User findById(@PathVariable("id") Long id); } /** * 回退類FeignClientFallback需實現Feign Client介面 * FeignClientFallback也可以是public class,沒有區別 */ @Component class FeignClientFallback implements UserFeignClient { @Override public User findById(Long id) { User user = new User(); user.setId(-1L); user.setUsername("預設使用者"); return user; } }
注意使用@Component時,不用配@ComponentScan,啟動類有整合
怎樣禁用單個FeignClient的Hystrix?
如同上面提到的,當有多個FeignClient介面類,怎麼禁用某個的hystrix呢?
在configuration類中加入:
@Bean @Scope("prototype") public Feign.Builder feignBuilder(){ return Feign.builder(); }
之所以可以如此是因為
Feign.Builder feignBuilder: HystrixFeign.Builder
預設就是使用Feign.Builder 支援hystrixFeign。
9.feign的hystrix fallbacks
如果你需要在觸發fallback觸發器時返回一個錯誤原因,你可以使用fallbackFactory:
@FeignClient(name = "microservice-provider-user", fallbackFactory = FeignClientFallbackFactory.class) public interface UserFeignClient { @RequestMapping(value = "/{id}", method = RequestMethod.GET) public User findById(@PathVariable("id") Long id); } /** * UserFeignClient的fallbackFactory類,該類需實現FallbackFactory介面,並覆寫create方法 */ @Component class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient> { private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFallbackFactory.class); @Override public UserFeignClient create(Throwable cause) { return new UserFeignClient() { @Override public User findById(Long id) { // 日誌最好放在各個fallback方法中,而不要直接放在create方法中。 // 否則在引用啟動時,就會列印該日誌。 // 詳見https://github.com/spring-cloud/spring-cloud-netflix/issues/1471 FeignClientFallbackFactory.LOGGER.info("fallback; reason was:", cause); User user = new User(); user.setId(-1L); user.setUsername("預設使用者"); return user; } }; } }