1. 程式人生 > >SpringCloud整合zuul並實現反向代理和負載均衡

SpringCloud整合zuul並實現反向代理和負載均衡

首先,這篇文章參考的是http://blog.didispace.com/springcloud5/這位大牛的部落格。本人是通過這篇部落格來學習zuul的,現在寫的部落格只是個人在學習時個人的一些感受和理解。

談到spring cloud,就要提及到其核心元件:zuul元件,這個元件其實功能很多,比如反向代理,負載均衡還有許可權控制等功能,這篇部落格主要寫的是zuul的反向代理和負載均衡。

首先是進行eureka的實現,程式碼如下:

首先是pom.xml,新增依賴:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.3.2.RELEASE</version>
        </dependency>

然後是application:

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(EurekaApplication.class).web(true).run(args);
    }
}

 

接著是配置檔案:

server.port=1111
#eureka.instance.hostname=localhost

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/

 

建立好eureka後,則是實現zuul:

首先是新增pom.xml檔案的依賴:

   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.3.4.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.2.RELEASE</version>
        </dependency>

 

然後是具體的實現,也非常簡單:

@EnableZuulProxy
@SpringCloudApplication
public class ZuulApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ZuulApplication.class).web(true).run(args);
    }

}

接下來是配置檔案:

spring.application.name=api-gateway
server.port=5555
 
# routes to serviceId 這裡邊是通過serviceid來繫結地址,當在路徑後新增/api-a/   則是訪問service-A對應的服務。
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=service-A
 
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=service-B
 
# routes to url  這裡是繫結具體的ip地址
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/
 
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

那麼,其實在配置完這個配置檔案後,其實zuul已經實現了反向代理和負載均衡的兩個功能了,可能有人這時候就納悶了,這裡不是隻是反向代理了嗎?怎麼實現負載均衡呢?其實zuul實現負載均衡很簡單,使用serviceId進行繫結後,如果有多個相同的serviceid,則會進行輪詢的方式進行訪問。這個在下文會有具體的結果截圖。

現在需要開啟建立兩個服務,具體的操作為實現a+b的操作,第一個為Service-A。

pom.xml中新增:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.2.RELEASE</version>
        </dependency>

然後是配置檔案:

spring.application.name=service-A

server.port=2224

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/

然後是一個客戶端和一個controller:

package com.example;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class ControllerApplicationA {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ControllerApplicationA.class).web(true).run(args);
    }
}

 

 

package com.example.web;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.*;

@RestController
public class ComputeController {

    @Autowired
    private DiscoveryClient client;

    @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
    public String add(@PathVariable Integer a,@PathVariable Integer b)
    {
        System.out.println("host:"+client.getLocalServiceInstance().getHost()+"   -----port:"+client.getLocalServiceInstance().getPort());
        return a+b+" ------      host:"+client.getLocalServiceInstance().getHost()+"   -----port:"+client.getLocalServiceInstance().getPort();
    }

}

這個客戶端的程式碼是用來進行具體的操作的,在這中間我們在返回值中新增具體的伺服器地址和埠號。

以同樣的方式再建立一個服務Service-B。

然後先啟動兩個服務,截圖如下:

這時候先不要急著訪問Service-A和B,我們將service-A和B中的配置檔案中的埠號修改後再啟動:

結果如下:

這時候我們看到了,serviceid為Service-A和B各有兩個,那麼接下來則是實驗zuul負載均衡的時候了,我們在此只測試Service-A:

第一次訪問http://localhost:5555/api-a/add/1/2:

第二次訪問:

因此這就實現了負載均衡,但是這個負載均衡是屬於客戶端的負載均衡。在這我也就簡要的說下客戶端負載均衡。

客戶端負載均衡:

基於客戶端的負載均衡,簡單的說就是在客戶端程式裡面,自己設定一個排程演算法,在向伺服器發起請求的時候,先執行排程演算法計算出向哪臺伺服器發起請求,然後再發起請求給伺服器。

特點:

  1. 由客戶端內部程式實現,不需要額外的負載均衡器軟硬體投入。
  2. 程式內部需要解決業務伺服器不可用的問題,伺服器故障對應用程式的透明度小。
  3. 程式內部需要解決業務伺服器壓力過載的問題。

使用場景:

  1. 可以選擇為初期簡單的負載均衡方案,和DNS負載均衡一樣。
  2. 比較適合於客戶端具有成熟的排程庫函式,演算法以及API等
  3. 畢竟適合對伺服器入流量較大的業務,如HTTP POST檔案上傳,FTP檔案上傳,Memcache大流量寫入。
  4. 可以結合其他負載均衡方案進行架構。

要更多幹貨、技術猛料的孩子,快點拿起手機掃碼關注我,我在這裡等你哦~