springcloud子模塊之間的通信


              springcloud子模塊之間的通信

1.搭建公共模塊common

2.在common層搭建domain層user

package cn.itsource.domain;

public class User {
    private Long id;

    private String username;

    private String password;

    public User() {
    }

    public User(Long id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

3.服務層編寫接口user-server

  1.導入依賴:服務層依賴common層

<dependency>
    <groupId>cn.itsource.springcloud</groupId>
    <artifactId>springcloud-common-user</artifactId>
    <version>...</version>
</dependency>

  2.創建controller

  

/**
 * 用戶提供者服務
 */
@RestController
public class UserProviderController {

    /**
     * 提供者方法,orderServer消費者來調用
     * @param id
     * @return
     */
    // @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    @GetMapping("/user/{id}")
    public User getUserById(@PathVariable("id")Long id){
        System.out.println("UserProviderController.getUserById被調用了......");
        return new User(id,"zs:"+id , "123");
    }
}

4.order-server消費者服務

  1.依賴common模塊

<dependency>
    <groupId>cn.itsource.springcloud</groupId>
    <artifactId>springcloud-common-user</artifactId>
    <version>...</version>
</dependency>

  2.定義RestTemplate的bean

  /**
     * SpringMvc提供的一個基於Rest風格的http調用工具
     * @return
     */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

  3.定義消費者的Controller

/**
 * 訂單消費者服務
 */
@RestController
public class OrderConsumerController {

    @Autowired
    private RestTemplate restTemplate ;

    /**
     * 該方法是瀏覽器來調用
     * @param id
     * @return
     */
    @GetMapping("/order/user/{id}")
    public User getUserById(@PathVariable("id") Long id){
        System.out.println("OrderConsumerController.getUserById被調用了......");
        String url = "http://localhost:2000/user/"+id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }
}

EurekaServer高可用集群:

一.單節點故障

1.什么是EurekaServer單節點故障

如果只有一個EurekaSever,如果EurekaSever掛了那么整個微服務都不可用

2.解決方案

EurekaServer高可用集群

二.EurekaServer集群

1.搭建EurekaServer集群

創建兩個本地域名 C:\Windows\System32\drivers\etc\hosts

127.0.0.1 peer1
127.0.0.1 peer2

修改注冊中心eureka-server-1000

server:
port: 1000
eureka:
instance:
  hostname: peer1
client:
  registerWithEureka: false #禁用注冊中心向自己注冊
  fetchRegistry: false #不讓注冊中心獲取服務的注冊列表
  serviceUrl:
    defaultZone: http://peer2:1001/eureka/
    #注冊中心的注冊地址 ,其他微服務需要向這個地址注冊

搭建第二個注冊中心eureka-server-1001 - 復制

server:
port: 1001
eureka:
instance:
  hostname: peer2
client:
  registerWithEureka: false #禁用注冊中心向自己注冊
  fetchRegistry: false #不讓注冊中心獲取服務的注冊列表
  serviceUrl:
    defaultZone: http://peer1:1000/eureka/
    #注冊中心的注冊地址 ,其他微服務需要向這個地址注冊
3.修改EurekaClient (UserServer ,OrderServer)
eureka:
client:
  serviceUrl:
    defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/ #注冊中心地址
    ...

五.Ribbon

ribbon是負載均衡器,是基於RestTemplate ,它賦予了RestTemplate 負載均衡的能力

一.集群和負載均衡原理

 

二.提供者user-server集群

1.創建user-server服務2001 - 賦值
2.修改配置
eureka:
  client:
    serviceUrl:
      defaultZone: http://peer1:1000/eureka/,http://peer2:1001/eureka/ #注冊中心地址
  instance:
    prefer-ip-address: true #使用ip地址注冊
    instance-id: user-server1  #指定服務的id
server:
  port: 2000 
spring:
  application:
    name: user-server
 

注意:instance-id需要修改 , 而 spring.application.name 不需要修改 , 端口需要修改

3.修改主類名,pom中的名字,parent中的模塊增加

三.order-server集成Ribbon

1.導入依賴
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
2.修改RestTemplate的Bean的定義
 /**
     * SpringMvc提供的一個基於Rest風格的http調用工具
     * @LoadBalanced :ribbon的負載均衡標簽,賦予RestTemplate有負債均衡的能力
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

 

@LoadBalanced :ribbon的負載均衡標簽,賦予RestTemplate有負債均衡的能力

3.修改Controller調用方式
 @GetMapping("/order/user/{id}")
    public User getUserById(@PathVariable("id") Long id){
        System.out.println("OrderConsumerController.getUserById被調用了......");
        //String url = "http://localhost:2000/user/"+id;
        String url = "http://user-server/user/"+id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }

修改效果: String url = "http://user-server/user/"+id;

ribbon默認使用的輪詢策略

六.Feign

一.什么是Feign

基於Ribbon封裝的客戶端負載均衡器

二.Feign的集成 - springcloud-dept-server-4000

1.導入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.配置類開啟Feign
@SpringBootApplication
@EnableFeignClients("cn.itsource.client")
public class DeptServerApplication4000 
...
3.編寫Feign的接口
/**
 * @FeignClient(value="user-server") : 針對於用戶服務調用的 Fiegn的客戶端接口
 *  value屬性就是該接口要調用的目標服務的名字
 * Feign是如何實現服務調用的:
 *   1.通過@FeignClient(value="user-server")標簽上的服務名字能夠找到要調用的目標服務
 *   2.通過接口中的方法的 @GetMapping的url路徑找到目標服務的controller的方法 ,
 *   所以要保證Feign客戶端接口的方法和目標服務的對應的方法要完全一致。
 *
 */
@FeignClient(value="user-server")
public interface UserFeignClient {
​
    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id")Long id);
}

Feign客戶端接口的方法和目標服務的對應的方法要完全一致

4.調用
@RestController
public class DeptConsumerController {
​
    @Autowired
    private UserFeignClient userFeignClient ;
​
    /**
     * 該方法是瀏覽器來調用
     * @param id
     * @return
     */
    @GetMapping("/dept/user/{id}")
    public User getUserById(@PathVariable("id") Long id){
        User user = userFeignClient.getUserById(id); //使用Feign的接口調用
        return user;
    }
}

 

 

七.Hystrix

一.雪崩效應

一個微服務的故障導致整個微服務調用鏈全部癱瘓

二.Hystrix介紹

解決服務器故障(雪崩)的一個組件 ,它可以實現:隔離 ,熔斷 ,降級,緩存

  • 隔離 :包括線程池隔離和信號量隔離,限制調用分布式服務的資源使用,某一個調用的服務出現問題不會影響其他服務調用。

  • 熔斷 :當請求次數達到規定的閥值都出現服務故障(超時),Hystrix就把服務標記為短路狀態.

    正常情況下,斷路器處於關閉狀態(Closed),如果調用持續出錯或者超時,電路被打開進入熔斷狀態(Open),后續一段時間內的所有調用都會被拒絕(Fail Fast),一段時間以后,保護器會嘗試進入半熔斷狀態(Half-Open),允許少量請求進來嘗試,
    如果調用仍然失敗,則回到熔斷狀態
    如果調用成功,則回到電路閉合狀態;
  • 降級 :高並發情況下 ,為了保證一些主要的服務有足夠的資源不出問題 ,會認為的關掉一些無關緊要的服務,然后返回一些托底的數據,給用戶一個友好的提示。

  • 緩存 :Hystrix內部會把請求做緩存

三.Ribbon集成Hystrix - springcloud-order-server-3000

1.導入依賴
    <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
2.controller方法貼注解
 /**
     * 該方法是瀏覽器來調用
     *  @HystrixCommand :開啟方法的短路功能 , 如果方法出現異常,會調用 fallbackMethod
     *  指向的方法 ,然后返回托底數據
     */
    @HystrixCommand(fallbackMethod = "getUserByIdFallback")
    @GetMapping("/order/user/{id}")
    public JsonResult getUserById(@PathVariable("id") Long id){
        System.out.println("OrderConsumerController.getUserById被調用了......");
        String url = "http://user-server/user/"+id;
        User user = restTemplate.getForObject(url, User.class);
        return JsonResult.me().setData(user);
    }
3.托底方法
 public JsonResult getUserByIdFallback(@PathVariable("id") Long id){
        return JsonResult.me().setSuccess(false)
        .setMessage("服務展示不可用,請騷后重試[服務降級]");
    }

注意:托底方法的參數和返回結果要和原方法一致

四.Feign集成Hystrix - springcloud-dept-server-4000

1.開啟Hystrix
feign:
  hystrix:
    enabled: true #開啟熔斷支持
  client:
    config:
      remote-service:           #服務名,填寫default為所有服務
        connectTimeout: 30000
        readTimeout: 30000
hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000
2.修改Fiegn客戶端接口
@FeignClient(value="user-server" ,fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
​
    @GetMapping("/user/{id}")
    User getUserById(@PathVariable("id")Long id);
}

fallback = UserFeignClientFallback.class : 該類是當前接口的實現類 ,也是托底數據所在的處理類

3.托底實現
@Component
public class UserFeignClientFallback implements UserFeignClient {
    @Override
    public User getUserById(Long id) {
        System.out.println("托底數據執行....");
        return new User(-1L,"托底數據","");
    }
}
​

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM