分布式微服务架构组件

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


分享到:


相關文章: