1.安裝sts(spring tool suite)
1.安裝後項目前有[boot],yml文件中編碼會有提示,不可不用
安裝參考:
http://www.itxxz.com/a/gaoji/2015/0120/eclipse_spring_tools.html
2.springboot中,最方便的是配置了熱部署
<!-- 熱部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
部署後項目前有[devtools],修改無需重啓
3.boot封裝了json,返回的對象都是json格式
2.依賴和集成
1.查看eureka依賴樹,euraka下有ribbon
eureka搭建完成後可以使用如下url查看
http://172.x.x.x:9080/eureka/apps
http://172.x.x.x:9080/eureka/apps/service-name
2.feign下有ribbon和hystrix,已經集成,只需要在feign中配置fallback即可
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; } }
更多功能看官文
詳細https://github.com/OpenFeign/feign和
cloud文檔http://cloud.spring.io/spring-cloud-static/Dalston.SR1/
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; } }; } }