《深刻實踐Spring Boot》閱讀筆記之二:分佈式應用開發

 

上篇文章總結了《深刻實踐Spring Boot》的第一部分,這篇文章介紹第二部分:分佈式應用開發,以及怎麼構建一個高性能的服務平臺。html

主要從如下幾個方面總結:前端

  • Spring Boot SSO
  • 使用分佈式文件系統
  • 雲應用開發
  • 構建高性能的服務平臺

Spring Boot SSO

上篇文章提到了安全設計,使用Spring Security進行用戶驗證和權限驗證,但一個企業級的應用系統可能存在不少應用系統,每一個應用系統都須要設計安全管理,但不可能爲每個應用系統都設計一套安全管理,這樣不但耗時耗力,並且要作重複的工做,也不適宜創建統一的用戶中心。vue

可使用單點登陸SSO的方式創建一個登陸認證系統,而且實現對用戶的統一管理。本章在使用Spring Security安全管理的基礎上,再結合OAuth2認證受權協議來實現的,它不但適用於大型的分佈式管理系統,也適用於爲第三方提供統一的用戶管理和認證的平臺。java

做者給出了一個完整的實例,以模塊化的設計方式進行實現,整個demo的代碼能夠在github上查看。(https://github.com/chenfromsz/spring-boot-ssomysql

demo說明

我在本地運行了demo,經過chrome查看了系統間跳轉的過程,先說明下模塊的劃分,而後看下運行效果。git

項目 工程 類型 功能
數據庫管理模塊 mysql 程序集成 數據庫管理
安全配置模塊 security 程序集成 安全策略配置和權限管理
登陸認證模塊 login Web應用 SSO登陸認證(80)
共享資源模塊 resource Web應用 共享資源(8083)
客戶端應用1 web1 Web應用 客戶端1(8081)
客戶端應用2 web2 Web應用 客戶端2(8082)

訪問首頁時,跳轉到登陸頁面,輸入正確的帳號、密碼、驗證碼。
登陸成功後,跳轉到首頁:
首頁github

訪問web1系統、web2系統時不須要從新登陸,會自動登陸:
web1系統首頁web

「登陸認證模塊」主要包括驗證用戶帳號、集成OAuth2服務端端功能。spring

「安全配置模塊」是一個公共模塊,集成了SSO客戶端的安全策略配置和權限管理功能,供客戶端引用。sql

「數據庫管理模塊」是一個公共模塊,主要提供數據庫的訪問功能,供其餘模塊使用。

「共享資源模塊」提供了一個簡單的公共服務,2個客戶端應用可經過spring-cloud-zuul直接調用。

後面會重點介紹下登陸認證模塊,其餘模塊比較簡單,再也不過多介紹。

模塊化設計能夠提升代碼的複用性,避免重複開發,實例中的「數據庫管理模塊」和「安全配置模塊」能夠被其餘模塊共用,減小大部分重複工做。
做者的這種設計方式值得咱們學習,在之後的系統設計中,應多借鑑這種方式。

登陸認證模塊

我畫了一個流程圖,先了解下用戶認證、權限驗證的基本過程:
基本處理流程

整個處理流程,Spring Security都幫咱們自動實現了,咱們只須要對帳號中心數據源、權限中心數據源進行配置和擴展,另外,能夠對登陸頁面進行擴展,配置權限管理規則、防攻擊策略、記住登陸狀態。

爲了實現多個系統只需登陸一次,須要集成OAuth2。添加spring-cloud-starter-oauth2依賴,編寫一個配置類,繼承AuthorizationServerConfigurerAdapter,並聲明下@EnableAuthrizationServer來啓用OAuth2的認證服務器功能。

OAuth2有不少受權機制,本例中使用authorization_code機制,具體配置就不過多說明了,能夠參考下面的幾篇文章:

[1] 初步理解Spring Security並實踐
[2] security OAuth2.0 提供者實現原理
[3] jwt token介紹
[4] security OAuth2.0 jwt完美整合例子

使用分佈式文件系統

有這樣一個問題,若是上傳文件,如上傳圖片,應該怎樣保存,保存在哪裏?

傳統的作法通常都保存在Web服務器所在機器中。但隨着業務的日益發展,可能上傳的文件會累積愈來愈多,單臺機器每每會不堪重負,再加上一些負載均衡的配置和服務,須要分佈式文件系統解決。

在諸多分佈式的文件系統中,FastDFS是比較優秀的分佈式文件系統。FastDFS是一個徹底開源的分佈式文件系統,使用比較簡單方便,並且性能也很優秀,存儲容量和訪問性能可按需求進行線性橫向擴展。

FastDFS服務端和客戶端的安排、配置、管理都比較簡單,書中描述的也比較詳細,就不在此贅述了。

雲應用開發

Spring Cloud 是一套雲應用開發工具集,爲分佈式的微服務開發提供了一整套簡單易用的使用工具。Spring Cloud主要包括配置管理、服務發現、動態路由、負載均衡、斷路器、安全管理、事件總線、分佈式消息等組件的開發工具包。

Spring Cloud與Spring Boot 關係密切,可以臻於完美的幾何使用。

本章重點介紹了配置服務、發現服務、動態路由和斷路器、監控服務。

配置服務

一個項目工程老是須要一些配置,好比,要配置服務器的端口、訪問數據庫的參數等。一個大型的分佈式系統可能存在不少這樣須要配置的項目工程,配置管理是一個龐大的工程,須要一個單獨的系統專門管理各個項目的配置。

經過Spring Cloud的配置管理,只需建立一個簡單的工程,就能夠實現分佈式配置管理服務,同時還支持在線更新。

第一步,配置管理服務器
引入spring-cloud-config-server依賴,建立一個主程序:

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigApplication{
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}

配置文件的存儲目前支持使用本地存儲、Git以及Subversion等方式。以Git方式爲例,說明本地配置文件:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/chenfromsz/spring-cloud-config-repo
  rabbitmq:
      addresses: ${vcap.services.${PREFIX:}rabbitmq.credentials.uri:amqp://${RABBITMQ_HOST:192.168.1.215}:${RABBITMQ_PORT:5672}}
      username: alan
      password: alan

服務端會自動從指定的git地址獲取配置信息。raabitmq的配置用於通知客戶端應用配置更新。

第二步,配置管理的客戶端
須要在工程中引入spring-cloud-starter-config依賴,使用配置管理服務以後,若是本地的配置文件與配置管理服務器的配置文件有相同的配置項,將優先使用配置管理服務器的配置項。

客戶端的配置文件bookstrap.yml以下:

spring:
  application:
    name: data
  profiles:
    active: development
  cloud:
    config:
      uri: http://localhost:8888
  rabbitmq:
        addresses: amqp://192.168.1.214:5672
        username: alan
        password: alan

其中,name用來指定應用的名稱和配置文件的名稱,uri設定配置服務服務端的地址和端口,profiles爲使用配置文件名稱的後綴部分,用於綁定不一樣的線上環境。

第三步,使用配置
若是配置文件中有cloud.config.test配置項,能夠這樣使用

@Value("${cloud.config.test:World!}") String msg;

另外,可使用spring-cloud-bus-amqp依賴,經過事件總線的方式,實如今線更新全部客戶端的配置。

發現服務

在分佈式系統中,可能存在不少應用和服務,各個服務瀆職自主地管理自身的數據。服務與服務之間,須要互相共享一些數據,傳統的方式須要本身編寫一些接口程序,還須要使用複雜的配置來實現,使用Spring Cloud能夠輕易作到這些。

第一步,建立發現服務器
引入spring-cloud-starter-eureka-server依賴,建立一個簡單的主程序便可:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryApplication.class, args);
    }
}

第二步,建立客戶端
引入spring-cloud-starter-eurake依賴,主程序中加入@EnableDiscoveryClient啓用發現服務的客戶端。

配置文件以下:

eureka:
  instance:
    hostname: discovery
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://192.168.1.221:${server.port}/eureka/
動態路由和斷路器

如何在服務間相互調用呢,可使用動態路由、斷路器和故障容錯等功能。

引入spring-cloud-starter-zuul、spring-cloud-starter-hystrix依賴,添加@EnableZuulProxy和@EnableHystrix註解便可。

爲了便於測試,能夠經過共享Rest資源將repository的類直接暴露出來,很神奇吧,以下:

@RepositoryRestResource(collectionResourceRel="users",path="users")
public interface UserRepository extends GraphRepository<User> {
    User findByName(@Param("name") String name);

    @Query("MATCH (u:User) WHERE u.name =~ ('(?i).*'+{name}+'.*') RETURN u")
    Collection<User> findByNameContaining(@Param("name") String name);

}

能夠經過http://localhost/usershttp://localhost/users/123 之類的方式訪問。

經過如下3種方式調用其餘服務對外暴露的接口:

  • JavaScript:前端直接調用
  • RestTemplate:後端調用
  • FeignClient:特殊方式

以RestTemplate爲例說明一個服務調用data服務的例子:

@Autowired @LoadBalanced
 RestTemplate restTemplate;
 @HystrixCommand(fallbackMethod = "getUserFallback")
     public User getUserByName(String name) {
         Map<String, Object> params = new HashMap<>();
         params.put("name", name);
         User user = restTemplate.getForObject("http://data/user/findByName?name={name}", User.class, params);

         return user;
 }

上面例子中使用了@HystrixCommand用於實現斷路器,當一個系統服務忽然出現故障時,會自動阻斷對服務的訪問和調用,轉而調用備用方法。

監控服務

分佈式服務系統中運行着不少服務,必須有一個管理機制和方法,可以一目瞭然地隨時瞭解各個服務的運行狀況及其健康指數。

使用Spring Cloud的監控服務,能夠實時監控應用的運行狀況。使用很簡單,引入spring-cloud-starter-hystrix-dashboard依賴,建立一個主程序便可:

@SpringBootApplication
@Controller
@EnableHystrixDashboard
public class HystrixApplication{
    @RequestMapping("/")
    public String home() {
        return "forward:/hystrix";
    }

    public static void main(String[] args) {
        SpringApplication.run(HystrixApplication.class, args);
    }
}

具體監控指標可參看官網文檔。

構建高性能的服務平臺

使用Spring Cloud開發的微服務,其獨立而又相對隔離的特性,與Docker的理念有殊途同歸之妙,因此使用Docker發佈微服務,可以發揮其最大的優點,而且能夠很是輕易地構建一個高性能和高可用的服務平臺。

Docker能夠很方便地建立和管理鏡像,以及管理已經生成的和正在運行的容器。鏡像是一種文件存儲方式,能夠把許多文件作成一個鏡像文件。容器是鏡像運行的一個實例,運行一個鏡像,就會生成一個容器,容器生成以後,就能夠在容器中管理應用系統了。

Docker的安裝和發佈服務,網上的資料不少,這裏就不贅述了。

另外,可使用其餘一些服務管理工具來構建高性能和高可用的服務平臺。docker-compose工具是Docker容器管理工具集,能夠很方便地用來建立和重建容器、執行啓動和中止容器等管理操做,以及查看整個服務體系的運行狀況和輸出日誌等。使用docker-compose工具,只要一條指令就能啓動整個分佈式服務體系。

經過本篇文章的介紹,你們能夠感覺到Spring Cloud在構建分佈式應用時提供的便捷性,減小了大量的工做量。同時爲咱們考慮了方方面面,加強了系統的穩定性、高性能。
做者把全部代碼都上傳到github,你們能夠直接運行demo深刻了解。
[1] Spring Boot SSO:https://github.com/chenfromsz/spring-boot-sso
[2] 雲應用開發:https://github.com/chenfromsz/spring-boot-cloud

 


情情說

 

相關文章
相關標籤/搜索