分佈式微服務架構組件

1、服務發現-Nacos

服務發現、配置管理、服務治理及管理,同類產品還有ZooKeeper、Eureka、Consul

分佈式微服務架構組件

https://nacos.io/zh-cn/docs/what-is-nacos.html

https://github.com/alibaba/spring-cloud-alibaba/blob/master/README-zh.md

springboot 服務發現配置

https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md

  1. 添加依賴。
<code>

<

dependency

>

 

<

groupId

>

com.alibaba.boot

groupId

>

 

<

artifactId

>

nacos-config-spring-boot-starter

artifactId

>

 

<

version

>

${latest.version}

version

>

dependency

>

/<code>

注意:版本 0.2.x.RELEASE 對應的是 Spring Boot 2.x 版本,版本 0.1.x.RELEASE 對應的是 Spring Boot 1.x 版本。

2.在 application.properties 中配置 Nacos server 的地址:

<code>

nacos.config.server-addr

=

127.0

.

0.1

:

8848

/<code>

3.在 application.properties 中配置應用名稱:

<code>  

application

:  

name

: microservicemall-coupon/<code>

4.在springboot啟動實例類上加上註解@EnableDiscoveryClient

5.啟動nacos服務,啟動項目,訪問
http://localhost:8848/nacos (nacos/nacos)

nacos 配置管理

https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md

1、導入
spring-cloud-starter-alibaba-nacos-config pom

<code>

<

dependency

>

   

<

groupId

>

com.alibaba.cloud

groupId

>

   

<

artifactId

>

spring-cloud-starter-alibaba-nacos-config

artifactId

>

dependency

>

/<code>

2、創建
/src/main/resources/bootstrap.properties文件,配置應用名稱和nacos服務器地址

<code>

spring.application.name

=nacos-config-example

spring.cloud.nacos.config.server-addr

=

127.0

.

0.1

:

8848

/<code>

3、Conroller 添加@RefreshScope註解,@Value(${配置項})調用

<code> 
 

class

SampleController

{ ​ String userName; ​ int age; }/<code>

4、nacos 編輯配置

Data ID 應用名稱.properties

bootstrap.properties 多文件配置及解析
<code>#應用名稱
spring.application.name=microservicemall-member
spring.cloud.nacos.

config

.server-addr=

127.0

.0

.1

:

8848

​ #nacos配置文件的命名空間 spring.cloud.nacos.

config

.namespace=e4843925

-3592

-474

d

-9

d08-bd5bb57b5366 #nacos配置文件所在組 spring.cloud.nacos.

config

.group=member ​ #通過多配置文件與nacos 解僱application.yml,將其分解為一下幾個獨立的配置文件,這樣只需要修改nacos相關的配置 所有的微服務應用都可以得到修改,不必一一去每個服務修改配置文件 #mysql鏈接配置 spring.cloud.nacos.

config

.ext-

config

[

0

].data-id=mysql.yml spring.cloud.nacos.

config

.ext-

config

[

0

].group=member #刷新生效設置 spring.cloud.nacos.

config

.ext-

config

[

0

].refresh=

true

​ spring.cloud.nacos.

config

.ext-

config

[

1

].data-id=mybatis.yml spring.cloud.nacos.

config

.ext-

config

[

1

].group=member spring.cloud.nacos.

config

.ext-

config

[

1

].refresh=

true

​ spring.cloud.nacos.

config

.ext-

config

[

2

].data-id=other.yml spring.cloud.nacos.

config

.ext-

config

[

2

].group=member spring.cloud.nacos.

config

.ext-

config

[

2

].refresh=

true

/<code>

2、遠程調用-feign

https://cloud.spring.io/spring-cloud-static/spring-cloud-openfeign/2.2.2.RELEASE/reference/html/

1、引入maven

<code>        

<

dependency

>

         

<

groupId

>

org.springframework.cloud

groupId

>

         

<

artifactId

>

spring-cloud-starter-openfeign

artifactId

>

     

dependency

>

/<code>

2、編寫遠程調用接口,通知springcloud這個接口需要調用遠程服務

<code> 

public

interface

CouponFeignService

{ ​    

public

R list(); }/<code>

3、開啟feigin客戶端

<code> 

public

class

MicroservicemallMemberApplication

{ .../<code>

4、調用示例

<code>@Autowired

private

CouponFeignService couponFeignService; ​ @RequestMapping(

"coupons"

)

public

R

test

()

{   MemberEntity memberEntity =

new

MemberEntity();   memberEntity.setNickname(

"張二狗"

);   R

list

= couponFeignService.

list

();  

return

R.ok().put(

"member"

,memberEntity).put(

"coupons"

,

list

.get(

"coupon"

)); }/<code>

3、網關-gateWay

1、作用

網關的角色是作為一個 API 架構,用來保護、增強和控制對於 API 服務的訪問。

API 網關是一個處於應用程序或服務(提供 REST API 接口服務)之前的系統,用來管理授權訪問控制流量限制等,這樣 REST API 接口服務就被 API 網關保護起來,對所有的調用者透明。因此,隱藏在 API 網關後面的業務系統就可以專注於創建和管理服務,而不用去處理這些策略性的基礎設施。

2、術語
  • Route(路由): 網關的基本模塊. 它由ID、目標URI、斷言集合和過濾器器集合組成。.如果斷言為真,則匹配路由.
  • Predicate(斷言): 這是一個Java 8函數斷言。輸入類型是SpringFramework ServerWebExchange。這允許您匹配來自HTTP請求的任何內容,例如請求頭或參數。
  • Filter: 這些是使用特定工廠構建的SpringFrameworkGatewayFilter的實例。在這裡,您可以在發送下游請求之前或之後修改請求和響應。
3、工作原理

客戶端向SpringCloudGateway提出請求。如果Gateway Handler映射確定請求與路由匹配,則將其發送到Gateway Web Handler。此處理程序通過特定於請求的篩選鏈運行請求。過濾器被虛線隔開的原因是過濾器可以在發送代理請求之前和之後運行邏輯。所有“預”過濾邏輯都被執行。然後發出代理請求。在發出代理請求後,將運行“POST”篩選邏輯。

4、路由配置規則

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.2.RELEASE/reference/html/#configuring-route-predicate-factories-and-gateway-filter-factories

4、數據校驗-JSR303

maven引用:hibernate-validator不引用jsr303不起作用的

<code>

<

dependency

>

 

<

groupId

>

javax.validation

groupId

>

 

<

artifactId

>

validation-api

artifactId

>

 

<

version

>

2.0.1.Final

version

>

dependency

>

<

dependency

>

 

<

groupId

>

org.hibernate

groupId

>

 

<

artifactId

>

hibernate-validator

artifactId

>

 

<

version

>

5.1.1.Final

version

>

dependency

>

/<code>

引用javax.validation包

1、配置校驗

bean上添加校驗註解 如@NotBlank

2、校驗生效

action參數上添加@Valid

3、自定義錯誤數據

參數後緊跟@BindingResult

<code>

public

R save( ArticleEntity article, BindingResult result) {    

if

(result.hasErrors()){        Map<

String

,

String

> map =

new

HashMap<>();        result.getFieldErrors().forEach((item)->{            

String

field = item.getField();            

String

message = item.getDefaultMessage();            map.put(field,message);       });        

return

R.error(

400

,

"提交數據不合法"

).put(

"data"

,map);   }

else

{   articleService.save(article);   }    

return

R.ok(); }/<code>
4、自定義註解

@Pattern,例如:

<code>  /<code>

擴展:@NotNull、@NotEmpty、@NotBlank區別

@NotNull:不能為null,但可以為empty

@NotEmpty:不能為null,而且長度必須大於0

@NotBlank:只能作用在String上,不能為null,而且調用trim()後,長度必須大於0

5、aop 統一處理校驗
<code>@Slf4j
@RestControllerAdvice(value = 

"com.cuzue.blog.article.controller"

) public

class

ExceptionControllerAdvice

{

       @ExceptionHandler(value = MethodArgumentNotValidException

.

class

)

   public R handleVaildException(MethodArgumentNotValidException exception){        log.error(exception.getMessage());        Map errorMap =

new

HashMap<>();        exception.getBindingResult().getFieldErrors().forEach(

(item)

->

{            String field = item.getField();            String message = item.getDefaultMessage();            errorMap.put(field,message);       });        

return

R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(),BizCodeEnum.VAILD_EXCEPTION.getMsg()).put(

"data"

,errorMap);   }        @ExceptionHandler(value = Exception

.

class

)

   public R handleException(Exception exception){        

return

R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(),BizCodeEnum.UNKNOW_EXCEPTION.getMsg());   } ​ }/<code>
<code>

public

enum

BizCodeEnum { ​    UNKNOW_EXCEPTION(

10000

,

"系統未知異常"

), ​    VAILD_EXCEPTION(

10001

,

"參數校驗失敗"

); ​    

private

int

code;    

private

String msg; ​    BizCodeEnum(

int

code, String msg) {        

this

.code = code;        

this

.msg = msg;   } ​    

public

int

getCode

()

{        

return

code;   } ​    

public

String

getMsg

()

{        

return

msg;   } }/<code>
6、校驗分組

實體類字段添加

<code>

@NotBlank

(message =

"文章名稱不能為空"

,groups = {

AddGroup

.class

,

UpdateGroup

.class

})/<code>

controller對應添加

<code>    

public

R

update

(

@Validated

(UpdateGroup.class)

@RequestBody

ArticleEntity article) {        

articleService

.updateById

(article); ​        

return

R

.ok

();   }/<code>

groups內容為接口類,該接口可以為空,也可以設置分組字段校驗排序。

默認沒有指定分組的校驗註解如@NotBlank,那麼在分組校驗情況@Validated(UpdateGroup.class)下不生效。

注意在使用@NotBlank等註解時,一定要和@valid一起使用,不然@NotBlank不起作用

5、接口文檔生成組件-Swagger

1、maven引用
<code>         
        

<

dependency

>

         

<

groupId

>

io.springfox

groupId

>

         

<

artifactId

>

springfox-swagger2

artifactId

>

         

<

version

>

2.9.2

version

>

     

dependency

>

     

<

dependency

>

         

<

groupId

>

io.springfox

groupId

>

         

<

artifactId

>

springfox-swagger-ui

artifactId

>

         

<

version

>

2.9.2

version

>

     

dependency

>

       

<

dependency

>

         

<

groupId

>

org.springframework.boot

groupId

>

         

<

artifactId

>

spring-boot-starter-web

artifactId

>

     

dependency

>

/<code>
2、配置Swagger
<code>

@Configuration

@EnableSwagger2

public class SwaggerConfig {    

@Bean

   public Docket createRestApi() {        

return

new

Docket

(DocumentationType.SWAGGER_2)              

.pathMapping

(

"/"

)              

.select

()              

.apis

(RequestHandlerSelectors.basePackage(

"com.cuzue.blog.article.controller"

))              

.paths

(PathSelectors.any())              

.build

()

.apiInfo

(new ApiInfoBuilder()                       .title(

"文章服務"

)                       .description(

"博客正文、分類欄目"

)                       .version(

"1.0"

)                       .contact(new Contact(

"張懷宇"

,

"www.cuzue.com"

,

"[email protected]"

))                       .license(

"The Apache License"

)                       .licenseUrl(

"http://www.cuzue.com"

)                       .build());   } }/<code>
3、controller註釋
<code>

@RequestMapping

(value =

"/update"

,method = RequestMethod.POST)    

@ApiOperation

(

"更新文章"

)    

@ApiImplicitParams

({            

@ApiImplicitParam

(name =

"ArticleEntity"

, value =

"文章實體"

,required = true),   }   )    public R update(

@Valid

@Validated

(UpdateGroup.class)

@RequestBody

ArticleEntity article) {        

articleService

.updateById

(article); ​        

return

R

.ok

();   }/<code>
4、訪問

ip:端口/swagger-ui.html

End


分享到:


相關文章: