溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

《深入實(shí)踐Spring Boot》閱讀筆記之二:分布式應(yīng)用開發(fā)

發(fā)布時(shí)間:2020-04-07 06:33:57 來源:網(wǎng)絡(luò) 閱讀:6020 作者:情情說 欄目:開發(fā)技術(shù)

上篇文章總結(jié)了《深入實(shí)踐Spring Boot》的第一部分,這篇文章介紹第二部分:分布式應(yīng)用開發(fā),以及怎么構(gòu)建一個(gè)高性能的服務(wù)平臺(tái)。

主要從以下幾個(gè)方面總結(jié):

  • Spring Boot SSO
  • 使用分布式文件系統(tǒng)
  • 云應(yīng)用開發(fā)
  • 構(gòu)建高性能的服務(wù)平臺(tái)
Spring Boot SSO

上篇文章提到了安全設(shè)計(jì),使用Spring Security進(jìn)行用戶驗(yàn)證和權(quán)限驗(yàn)證,但一個(gè)企業(yè)級的應(yīng)用系統(tǒng)可能存在很多應(yīng)用系統(tǒng),每個(gè)應(yīng)用系統(tǒng)都需要設(shè)計(jì)安全管理,但不可能為每一個(gè)應(yīng)用系統(tǒng)都設(shè)計(jì)一套安全管理,這樣不但耗時(shí)耗力,而且要做重復(fù)的工作,也不適宜建立統(tǒng)一的用戶中心。

可以使用單點(diǎn)登錄SSO的方式建立一個(gè)登錄認(rèn)證系統(tǒng),并且實(shí)現(xiàn)對用戶的統(tǒng)一管理。本章在使用Spring Security安全管理的基礎(chǔ)上,再結(jié)合OAuth3認(rèn)證授權(quán)協(xié)議來實(shí)現(xiàn)的,它不但適用于大型的分布式管理系統(tǒng),也適用于為第三方提供統(tǒng)一的用戶管理和認(rèn)證的平臺(tái)。

作者給出了一個(gè)完整的實(shí)例,以模塊化的設(shè)計(jì)方式進(jìn)行實(shí)現(xiàn),整個(gè)demo的代碼可以在github上查看。(https://github.com/chenfromsz/spring-boot-sso)

demo說明

我在本地運(yùn)行了demo,通過chrome查看了系統(tǒng)間跳轉(zhuǎn)的過程,先說明下模塊的劃分,然后看下運(yùn)行效果。

項(xiàng)目 工程 類型 功能
數(shù)據(jù)庫管理模塊 mysql 程序集成 數(shù)據(jù)庫管理
安全配置模塊 security 程序集成 安全策略配置和權(quán)限管理
登錄認(rèn)證模塊 login Web應(yīng)用 SSO登錄認(rèn)證(80)
共享資源模塊 resource Web應(yīng)用 共享資源(8083)
客戶端應(yīng)用1 web1 Web應(yīng)用 客戶端1(8081)
客戶端應(yīng)用2 web2 Web應(yīng)用 客戶端2(8082)

訪問首頁時(shí),跳轉(zhuǎn)到登錄頁面,輸入正確的賬號、密碼、驗(yàn)證碼。
登錄成功后,跳轉(zhuǎn)到首頁:
《深入實(shí)踐Spring Boot》閱讀筆記之二:分布式應(yīng)用開發(fā)

訪問web1系統(tǒng)、web2系統(tǒng)時(shí)不需要重新登錄,會(huì)自動(dòng)登錄:
《深入實(shí)踐Spring Boot》閱讀筆記之二:分布式應(yīng)用開發(fā)

「登錄認(rèn)證模塊」主要包括驗(yàn)證用戶賬號、集成OAuth3服務(wù)端端功能。

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

「數(shù)據(jù)庫管理模塊」是一個(gè)公共模塊,主要提供數(shù)據(jù)庫的訪問功能,供其他模塊使用。

「共享資源模塊」提供了一個(gè)簡單的公共服務(wù),2個(gè)客戶端應(yīng)用可通過spring-cloud-zuul直接調(diào)用。

后面會(huì)重點(diǎn)介紹下登錄認(rèn)證模塊,其他模塊比較簡單,不再過多介紹。

模塊化設(shè)計(jì)可以提高代碼的復(fù)用性,避免重復(fù)開發(fā),實(shí)例中的「數(shù)據(jù)庫管理模塊」和「安全配置模塊」可以被其他模塊共用,減少大部分重復(fù)工作。
作者的這種設(shè)計(jì)方式值得我們學(xué)習(xí),在以后的系統(tǒng)設(shè)計(jì)中,應(yīng)多借鑒這種方式。

登錄認(rèn)證模塊

我畫了一個(gè)流程圖,先了解下用戶認(rèn)證、權(quán)限驗(yàn)證的基本過程:
《深入實(shí)踐Spring Boot》閱讀筆記之二:分布式應(yīng)用開發(fā)

整個(gè)處理流程,Spring Security都幫我們自動(dòng)實(shí)現(xiàn)了,我們只需要對賬號中心數(shù)據(jù)源、權(quán)限中心數(shù)據(jù)源進(jìn)行配置和擴(kuò)展,另外,可以對登錄頁面進(jìn)行擴(kuò)展,配置權(quán)限管理規(guī)則、防***策略、記住登錄狀態(tài)。

為了實(shí)現(xiàn)多個(gè)系統(tǒng)只需登錄一次,需要集成OAuth3。添加spring-cloud-starter-oauth3依賴,編寫一個(gè)配置類,繼承AuthorizationServerConfigurerAdapter,并聲明下@EnableAuthrizationServer來啟用OAuth3的認(rèn)證服務(wù)器功能。

OAuth3有很多授權(quán)機(jī)制,本例中使用authorization_code機(jī)制,具體配置就不過多說明了,可以參考下面的幾篇文章:

[1] 初步理解Spring Security并實(shí)踐
[2] security OAuth3.0 提供者實(shí)現(xiàn)原理
[3] jwt token介紹
[4] security OAuth3.0 jwt完美整合例子

使用分布式文件系統(tǒng)

有這樣一個(gè)問題,如果上傳文件,如上傳圖片,應(yīng)該怎樣保存,保存在哪里?

傳統(tǒng)的做法一般都保存在Web服務(wù)器所在機(jī)器中。但隨著業(yè)務(wù)的日益發(fā)展,可能上傳的文件會(huì)累積越來越多,單臺(tái)機(jī)器往往會(huì)不堪重負(fù),再加上一些負(fù)載均衡的配置和服務(wù),需要分布式文件系統(tǒng)解決。

在諸多分布式的文件系統(tǒng)中,F(xiàn)astDFS是比較優(yōu)秀的分布式文件系統(tǒng)。FastDFS是一個(gè)完全開源的分布式文件系統(tǒng),使用比較簡單方便,而且性能也很優(yōu)秀,存儲(chǔ)容量和訪問性能可按需求進(jìn)行線性橫向擴(kuò)展。

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

云應(yīng)用開發(fā)

Spring Cloud 是一套云應(yīng)用開發(fā)工具集,為分布式的微服務(wù)開發(fā)提供了一整套簡單易用的使用工具。Spring Cloud主要包括配置管理、服務(wù)發(fā)現(xiàn)、動(dòng)態(tài)路由、負(fù)載均衡、斷路器、安全管理、事件總線、分布式消息等組件的開發(fā)工具包。

Spring Cloud與Spring Boot 關(guān)系密切,能夠臻于完美的幾何使用。

本章重點(diǎn)介紹了配置服務(wù)、發(fā)現(xiàn)服務(wù)、動(dòng)態(tài)路由和斷路器、監(jiān)控服務(wù)。

配置服務(wù)

一個(gè)項(xiàng)目工程總是需要一些配置,比如,要配置服務(wù)器的端口、訪問數(shù)據(jù)庫的參數(shù)等。一個(gè)大型的分布式系統(tǒng)可能存在很多這樣需要配置的項(xiàng)目工程,配置管理是一個(gè)龐大的工程,需要一個(gè)單獨(dú)的系統(tǒng)專門管理各個(gè)項(xiàng)目的配置。

通過Spring Cloud的配置管理,只需創(chuàng)建一個(gè)簡單的工程,就可以實(shí)現(xiàn)分布式配置管理服務(wù),同時(shí)還支持在線更新。

第一步,配置管理服務(wù)器
引入spring-cloud-config-server依賴,創(chuàng)建一個(gè)主程序:

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

配置文件的存儲(chǔ)目前支持使用本地存儲(chǔ)、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

服務(wù)端會(huì)自動(dòng)從指定的git地址獲取配置信息。raabitmq的配置用于通知客戶端應(yīng)用配置更新。

第二步,配置管理的客戶端
需要在工程中引入spring-cloud-starter-config依賴,使用配置管理服務(wù)之后,如果本地的配置文件與配置管理服務(wù)器的配置文件有相同的配置項(xiàng),將優(yōu)先使用配置管理服務(wù)器的配置項(xiàng)。

客戶端的配置文件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用來指定應(yīng)用的名稱和配置文件的名稱,uri設(shè)定配置服務(wù)服務(wù)端的地址和端口,profiles為使用配置文件名稱的后綴部分,用于綁定不同的線上環(huán)境。

第三步,使用配置
如果配置文件中有cloud.config.test配置項(xiàng),可以這樣使用

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

另外,可以使用spring-cloud-bus-amqp依賴,通過事件總線的方式,實(shí)現(xiàn)在線更新所有客戶端的配置。

發(fā)現(xiàn)服務(wù)

在分布式系統(tǒng)中,可能存在很多應(yīng)用和服務(wù),各個(gè)服務(wù)瀆職自主地管理自身的數(shù)據(jù)。服務(wù)與服務(wù)之間,需要互相共享一些數(shù)據(jù),傳統(tǒng)的方式需要自己編寫一些接口程序,還需要使用復(fù)雜的配置來實(shí)現(xiàn),使用Spring Cloud可以輕易做到這些。

第一步,創(chuàng)建發(fā)現(xiàn)服務(wù)器
引入spring-cloud-starter-eureka-server依賴,創(chuàng)建一個(gè)簡單的主程序即可:

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

第二步,創(chuàng)建客戶端
引入spring-cloud-starter-eurake依賴,主程序中加入@EnableDiscoveryClient啟用發(fā)現(xiàn)服務(wù)的客戶端。

配置文件如下:

eureka:
  instance:
    hostname: discovery
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://192.168.1.221:${server.port}/eureka/
動(dòng)態(tài)路由和斷路器

如何在服務(wù)間相互調(diào)用呢,可以使用動(dòng)態(tài)路由、斷路器和故障容錯(cuò)等功能。

引入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/users , http://localhost/users/123 之類的方式訪問。

通過以下3種方式調(diào)用其他服務(wù)對外暴露的接口:

  • JavaScript:前端直接調(diào)用
  • RestTemplate:后端調(diào)用
  • FeignClient:特殊方式

以RestTemplate為例說明一個(gè)服務(wù)調(diào)用data服務(wù)的例子:

 @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用于實(shí)現(xiàn)斷路器,當(dāng)一個(gè)系統(tǒng)服務(wù)突然出現(xiàn)故障時(shí),會(huì)自動(dòng)阻斷對服務(wù)的訪問和調(diào)用,轉(zhuǎn)而調(diào)用備用方法。

監(jiān)控服務(wù)

分布式服務(wù)系統(tǒng)中運(yùn)行著很多服務(wù),必須有一個(gè)管理機(jī)制和方法,能夠一目了然地隨時(shí)了解各個(gè)服務(wù)的運(yùn)行情況及其健康指數(shù)。

使用Spring Cloud的監(jiān)控服務(wù),可以實(shí)時(shí)監(jiān)控應(yīng)用的運(yùn)行情況。使用很簡單,引入spring-cloud-starter-hystrix-dashboard依賴,創(chuàng)建一個(gè)主程序即可:

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

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

具體監(jiān)控指標(biāo)可參看官網(wǎng)文檔。

構(gòu)建高性能的服務(wù)平臺(tái)

使用Spring Cloud開發(fā)的微服務(wù),其獨(dú)立而又相對隔離的特性,與Docker的理念有異曲同工之妙,所以使用Docker發(fā)布微服務(wù),能夠發(fā)揮其最大的優(yōu)勢,并且可以非常輕易地構(gòu)建一個(gè)高性能和高可用的服務(wù)平臺(tái)。

Docker可以很方便地創(chuàng)建和管理鏡像,以及管理已經(jīng)生成的和正在運(yùn)行的容器。鏡像是一種文件存儲(chǔ)方式,可以把許多文件做成一個(gè)鏡像文件。容器是鏡像運(yùn)行的一個(gè)實(shí)例,運(yùn)行一個(gè)鏡像,就會(huì)生成一個(gè)容器,容器生成之后,就可以在容器中管理應(yīng)用系統(tǒng)了。

Docker的安裝和發(fā)布服務(wù),網(wǎng)上的資料很多,這里就不贅述了。

另外,可以使用其他一些服務(wù)管理工具來構(gòu)建高性能和高可用的服務(wù)平臺(tái)。docker-compose工具是Docker容器管理工具集,可以很方便地用來創(chuàng)建和重建容器、執(zhí)行啟動(dòng)和停止容器等管理操作,以及查看整個(gè)服務(wù)體系的運(yùn)行情況和輸出日志等。使用docker-compose工具,只要一條指令就能啟動(dòng)整個(gè)分布式服務(wù)體系。

通過本篇文章的介紹,大家可以感受到Spring Cloud在構(gòu)建分布式應(yīng)用時(shí)提供的便捷性,減少了大量的工作量。同時(shí)為我們考慮了方方面面,增強(qiáng)了系統(tǒng)的穩(wěn)定性、高性能。
作者把所有代碼都上傳到github,大家可以直接運(yùn)行demo深入了解。
[1] Spring Boot SSO:https://github.com/chenfromsz/spring-boot-sso
[2] 云應(yīng)用開發(fā):https://github.com/chenfromsz/spring-boot-cloud

《深入實(shí)踐Spring Boot》閱讀筆記之二:分布式應(yīng)用開發(fā)

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI