[SpringCloud]リボンのロードバランシング

現在、残りの方法により、2つの方法で春のクラウドサービスコールの間:

  1. 見せ掛けます
  2. 残りのテンプレート+リボン

リボンは、アルゴリズムのバランスをとる負荷分散と負荷をカスタマイズすることができますので、道よりエレガントで(内部の負荷分散を行うためにも使用リボン)を使用する方が簡単装うが、我々はそれを使用する2番目のシナリオ

1.何ですか

  ネットフリックスは、オープンソースプロジェクトをリリースしている、主な機能は提供することを目的とするクライアントソフトウェア負荷分散アルゴリズム、一緒にNetflixのサービスを接続する中間層を。(LBと呼ばれる)コンフィギュレーションファイルに記載されているロードバランサ一定のルールに基づいてマシンを接続するために自動的にリボン助けあなたの後に、マシンのすべてのバックは、(単純なポーリング、ランダム接続など)は、ロード・バランシングは定義から達成することができますアルゴリズム。

  ダボとSpringCloudは、両方のロードバランシングを提供しますが、SpringCloud負荷分散アルゴリズムをカスタマイズすることができます

2. LB知識

  高可用性システムHA(利用可能な高)を達成するようにLBロードバランシング(負荷分散)、頻繁に使用される微小の分散クラスタ内のアプリケーションまたはサービスは、ユーザが一般的に使用される、サービスに対する複数の要求にわたって償却されます負荷分散ソフトウェアnginxの、LVS、その上F5のハードウェアとがあります。
LBは、に分かれています。

  1. 一元LB
    アクセス要求が戦略を通じて、サービスプロバイダに転送されるため、消費者やサービスプロバイダーLB施設(例えばF5、などnginxのようなソフトウェア、ハードウェア)の間で分離され、施設が責任があります
  2. LBの内のプロセス
    、これらのアドレスから適切なサーバの選択に、サービスの消費者への今後のLB論理連続、アドレスは、サービスレジストリから入手可能であるかを取得するために、消費者、そして自分自身。リボンが過程でLBに属している、それはそれを通じて、サービスプロバイダのアドレスを取得するだけで、クラスライブラリ、統合された消費者法、消費者

LBのアイデア3.リボン

  1. まずEurekaServer、同じ領域少ない負荷での設定を選択EurekaServer
  2. そして、ユーザーが指定したポリシーに従って、登録EurekaServerのリストからアドレスを選択したサービスを取得

前記コア成分のiRule

iRule:あなたは、特定のアルゴリズムに基づいてリストからサービスにアクセスしたいサービスを選択するには、7つの戦略を提供します。

  1. RoundRobinRule:世論調査
  2. RandomRule:ランダム
  3. AvailabilityFilteringRule:ポーリングポリシーに従ってアクセス可能なサービスの最初による多元接続状態トリップ回路遮断器の故障、ならびに同時接続の数にサービスを除外しますが、サービスの閾値を超え、残りのリスト
  4. WeightedResponseTimeRule:平均応答時間重みに基づいて、すべてのサービスの計算、より大きな重みが選択された迅速なサービスの応答時間確率。ただ、統計が不足している場合、使用RoundRobinRule戦略、十分な統計情報は、WeightedResponseTimeRuleに切り替わります開始
  5. RetryRule:サービスが指定された時間内に再試行を取得するために失敗した場合、最初のRoundRobinRule戦略に合わせてサービスを取得するには、利用可能なサービスへのアクセス
  6. BestAvailableRule:最初に起因する短絡トリップ状態で複数の障害にアクセスサービスをフィルタリングし、同時サービスの最小量を選択します
  7. ZoneAvoidanceRule:サーバ選択サーバ地域のサーバーのパフォーマンスと可用性を配合

次のようにも方針、手続きをカスタマイズすることができます。

  1. コンフィギュレーション・クラスのiRuleの豆カスタムの戻り値の型

    @Configuration
    public class MySelfRule
    {
    	@Bean
    	public IRule myRule()
    	{
    		//return new RandomRule();// Ribbon默认是轮询,我自定义为随机
    		//return new RoundRobinRule();// Ribbon默认是轮询,我自定义为随机
    		
    		return new RandomRule_ZY();// 我自定义为每台机器5次
    	}
    }
    //----------------------自定义路由策略类---------------
    public class RandomRule_ZY extends AbstractLoadBalancerRule
    {
    // total = 0 // 当total==5以后,我们指针才能往下走,
    // index = 0 // 当前对外提供服务的服务器地址,
    // total需要重新置为零,但是已经达到过一个5次,我们的index = 1
    // 分析:我们5次,但是微服务只有8001 8002 8003 三台,OK?
    // 
    
    
    private int total = 0; 			// 总共被调用的次数,目前要求每台被调用5次
    private int currentIndex = 0;	// 当前提供服务的机器号
    
    public Server choose(ILoadBalancer lb, Object key)
    {
    	if (lb == null) {
    		return null;
    	}
    	Server server = null;
    
    while (server == null) {
    	if (Thread.interrupted()) {
    		return null;
    	}
    	List<Server> upList = lb.getReachableServers();
    	List<Server> allList = lb.getAllServers();
    
    	int serverCount = allList.size();
    	if (serverCount == 0) {
    		/*
    		 * No servers. End regardless of pass, because subsequent passes only get more
    		 * restrictive.
    		 */
    		return null;
    	}
    //			int index = rand.nextInt(serverCount);// java.util.Random().nextInt(3);
    //			server = upList.get(index);
    
    			
    //			private int total = 0; 			// 总共被调用的次数,目前要求每台被调用5次
    //			private int currentIndex = 0;	// 当前提供服务的机器号
                if(total < 5)
                {
    	            server = upList.get(currentIndex);
    	            total++;
                }else {
    	            total = 0;
    	            currentIndex++;
    	            if(currentIndex >= upList.size())
    	            {
    	              currentIndex = 0;
    	            }
                }					
    			if (server == null) {
    				/*
    				 * The only time this should happen is if the server list were somehow trimmed.
    				 * This is a transient condition. Retry after yielding.
    				 */
    				Thread.yield();
    				continue;
    			}
    
    	if (server.isAlive()) {
    		return (server);
    	}
    
    	// Shouldn't actually happen.. but must be transient or a bug.
    	server = null;
    	Thread.yield();
    }
    
    return server;
    
    }
    
    @Override
    public Server choose(Object key)
    {
    	return choose(getLoadBalancer(), key);
    }
    
    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig)
    {
    	// TODO Auto-generated method stub
    
    }
    

    }

  2. それはコンフィギュレーションをロードするために開始し、起動クラスのルーティングポリシー@RibbonClient上のカスタム構成、

    @SpringBootApplication
    @EnableEurekaClient
    //在启动该微服务的时候就能去加载我们的自定义Ribbon配置类,从而使配置生效
    //@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
    @RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
    public class DeptConsumer80_App
    {
    	public static void main(String[] args)
    	{
    		SpringApplication.run(DeptConsumer80_App.class, args);
    	}
    }
    

注:カスタム設定クラスが現在のパッケージの下に配置することができませんスキャンし、下のサブパッケージ、または当社のカスタム設定クラスは、すべてのクライアントリボンロックによって共有される、それは、最大ではありません@ComponentScan 専門のカスタムの目的

5.実装

5.1設定ファイルの方法

書式を設定します:<client>.<nameSpace>.<property>=<value>

  • クライアントクライアント名:サービス名の外部被ばくのサービスプロバイダ
  • 名前空間の名前空間について:デフォルトはリボンです
  • プロパティはプロパティ名:当社の戦略は、ロードバランシングを設定することですNFLoadBalancerRuleClassName cloud-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
### 针对单个服务的 Ribbon 配置
MICROSERVICECLOUD-DEPT:
  ribbon: 
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

右の名前の前に、ポリシーをグローバル負荷分散の設定はサービスから削除することができます

5.2注釈モード

示例如下6

6.プロジェクトの戦闘

6.1リードを頼ります

<!-- Ribbon相关 -->
<!-- Eureka -->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<!-- Ribbon -->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<!-- Eureka相关 -->
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

6.2コンフィギュレーションファイル

eureka:
  client:
    register-with-eureka: false
    service-url: 
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/  

消費者(クライアント)で6.3起動時の構成スタートアップ項目

@SpringBootApplication
@EnableEurekaClient
// name:要调用服务(提供者)的名称,针对单个该服务使用的LB策略,默认是轮询
@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=RetryRule.class)
public class DeptConsumer80_App
{
	public static void main(String[] args)
	{
		SpringApplication.run(DeptConsumer80_App.class, args);
	}

    @Bean
   	@LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 , 负载均衡的工具。
   	public RestTemplate getRestTemplate()
   	{
   		return new RestTemplate();
   	}

}

各クライアントは、もはや書かれているようにRestTemplateも、一様分布の中央に書き込むことはできません

    @Bean
   	@LoadBalanced//Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 , 负载均衡的工具。
   	public RestTemplate getRestTemplate()
   	{
   		return new RestTemplate();
   	}

6.4サービス層はサービスを呼び出します


// 注意,这些的是注册到Eureka上服务的名称地址,不是通过ip调用的。
// 直接调用服务而不用在关心地址和端口号
//private static final String REST_URL_PREFIX = "http://localhost:8001";
private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT";

	/**
	 * 使用 使用restTemplate访问restful接口非常的简单粗暴无脑。
	 *  (url, requestMap, ResponseBean.class)这三个参数分别代表 REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。
	 */
	@Autowired
	private RestTemplate restTemplate;

	@RequestMapping(value = "/consumer/dept/add")
	public boolean add(Dept dept)
	{
		。。。逻辑代码
		// 请求地址:服务地址+方法路径,参数,返回类型,这样就实现了调用别的服务
		// 完成真正的通过微服务名字从Eureka萨汗找到服务并访问
		return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
		。。。逻辑代码
	}

おすすめ

転載: blog.csdn.net/wrs120/article/details/91573056