springcloud 入門筆記-1


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;
      }
    };
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章