Spring Cloud Alibaba快速上手、项目搭建教程

因为之前学过Eureka 所以很多基础的设置就不记录了

本文对应的项目代码-CloudBase

几个仓库供学习参考

Spring Cloud基础教程

涵盖大部分核心组件使用的Spring Cloud教程

写在前面(相关更新)

2021.1.15

提交了一个根据vue-admin-template修改的一个基本的前端架子
然后跟本项目做了联调 实现了登录注销等、用户信息的获取是在consumer模块中 把信息写死了 admin角色
前端仓库-VueAdmin


1.版本选择

image-20201217095436779

image-20201217095452197

2.Nacos作为注册中心和配置中心

注册中心

下载自行百度 顺便可以把sentinal-dashboard也下载了 跟Eureka不同 nacos可以直接使用jar包启动就行了

然后访问localhost:8848/nacos 就可以进入页面了 账号密码都是nacos (sentinal的dashboard的登录账号密码都是sentinal)

只需要下面三步 启动就可以注册上nacos里了

  <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

image-20201229195338276

server:
  port: 8881
spring:
  application:
    name: cloudstudy-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

配置中心

导入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

server:
  port: 9101
spring:
#配置环境
  #profiles:
    #active: dev
  application:
    name: nacos-config-client
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 #Nacos地址
      config:
        server-addr: localhost:8848 #Nacos地址
        file-extension: yml #这里我们获取的yaml格式的配置

项目的配置文件要使用bootstrap.yml 配置信息如上

nacos中的配置文件的dataid的组成格式及与SpringBoot配置文件中的属性对应关系

spring.profiles.active为配置的环境

假设我当前项目用的是dev环境 项目名为consumer 后缀是yml 那么组合起来就是 consumer-dev.yml 就会根据这个去配置中心找对应的文件 读取

${
   spring.application.name}-${
   spring.profiles.active}.${
   spring.cloud.nacos.config.file-extension}

image-20201230113347579

对应在nacos上创建配置文件 然后测试一下是否将配置文件记载进来 使用@Value注入

然后调用接口返回值 是否对应配置的值即可验证

image-20201230113423377

添加其他的配置文件 共享一些公共的配置 例如mysql redis之类的

    #共享配置文件
        shared-configs[0]:
          data-id: commom.yml
          group: DEFAULT_GROUP
          refresh: true  #要配置刷新

# 这样也可以共享配置文件
#        extension-configs[0]:
#          - data-id: shareconfig3.yml
#            group: SHARE3_GROUP
#            refresh: true

看启动的控制台可以发现加载到了对应的两个配置文件

image-20201230112237698

3.服务消费的方式

使用RestTemplate

在之前的例子中,已经使用过RestTemplate来向服务的某个具体实例发起HTTP请求,但是具体的请求路径是通过拼接完成的,对于开发体验并不好。但是,实际上,在Spring Cloud中对RestTemplate做了增强,只需要稍加配置,就能简化之前的调用方式。

比如:

@EnableDiscoveryClient
@SpringBootApplication
public class TestApplication {

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

    @Slf4j
    @RestController
    static class TestController {

        @Autowired
        RestTemplate restTemplate;

        @GetMapping("/test")
        public String test() {
            String result = restTemplate.getForObject("http://alibaba-nacos-discovery-server/hello?name=didi", String.class);
            return "Return : " + result;
        }
    }

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

可以看到,在定义RestTemplate的时候,增加了@LoadBalanced注解,而在真正调用服务接口的时候,原来host部分是通过手工拼接ip和端口的,直接采用服务名的时候来写请求路径即可。在真正调用的时候,Spring Cloud会将请求拦截下来,然后通过负载均衡器选出节点,并替换服务名部分为具体的ip和端口,从而实现基于服务名的负载均衡调用。

使用WebClient(可以不看)

WebClient是Spring 5中最新引入的,可以将其理解为reactive版的RestTemplate。下面举个具体的例子,它将实现与上面RestTemplate一样的请求调用:

@EnableDiscoveryClient
@SpringBootApplication
public class TestApplication {

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

    @Slf4j
    @RestController
    static class TestController {

        @Autowired
        private WebClient.Builder webClientBuilder;

        @GetMapping("/test")
        public Mono<String> test() {
            Mono<String> result = webClientBuilder.build()
                    .get()
                    .uri("http://alibaba-nacos-discovery-server/hello?name=didi")
                    .retrieve()
                    .bodyToMono(String.class);
            return result;
        }
    }

    @Bean
    @LoadBalanced
    public WebClient.Builder loadBalancedWebClientBuilder() {
        return WebClient.builder();
    }

}

可以看到,在定义WebClient.Builder的时候,也增加了@LoadBalanced注解,其原理与之前的RestTemplate时一样的。关于WebClient的完整例子也可以通过在文末的仓库中查看。

使用Feign(建议使用 与平常的SpringBoot项目类似 Controller调用Service层 只不过service层使用feign去调用对应的服务提供者的接口)

上面介绍的RestTemplate和WebClient都是Spring自己封装的工具,下面介绍一个Netflix OSS中的成员,通过它可以更方便的定义和使用服务消费客户端。下面也举一个具体的例子,其实现内容与上面两种方式结果一致:

第一步:在pom.xml中增加openfeign的依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

第二步:定义Feign客户端和使用Feign客户端:

@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class TestApplication {

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

    @Slf4j
    @RestController
    static class TestController {

        @Autowired
        Client client;

        @GetMapping("/test")
        public String test() {
            String result = client.hello("didi");
            return "Return : " + result;
        }
    }


    @FeignClient("alibaba-nacos-discovery-server")
    interface Client {

        @GetMapping("/hello")
        String hello(@RequestParam(name = "name") String name);

    }

}

这里主要先通过@EnableFeignClients注解开启扫描Spring Cloud Feign客户端的功能;然后又创建一个Feign的客户端接口定义。使用@FeignClient注解来指定这个接口所要调用的服务名称,接口中定义的各个函数使用Spring MVC的注解就可以来绑定服务提供方的REST接口,比如下面就是绑定alibaba-nacos-discovery-server服务的/hello接口的例子。最后,在Controller中,注入了Client接口的实现,并调用hello方法来触发对服务提供方的调用。

feign相关配置

cloudstudy-provider: #对应FeignClient注解上的服务名
    ribbon:
      #    NFLoadBalancerRuleClassName: com.zyfgoup.config.MyRule  #自己写的只取第一个服务
      #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #配置规则 随机
      #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询
      #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RetryRule #配置规则 重试
      #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重
      NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule #配置规则 最空闲连接策略
      ConnectTimeout: 500 #请求连接超时时间
      ReadTimeout: 1000 #请求处理的超时时间
      OkToRetryOnAllOperations: true #对所有请求都进行重试
      MaxAutoRetriesNextServer: 2 #切换实例的重试次数
      MaxAutoRetries: 1 #对当前实例的重试次数

深入思考

不论我用的是RestTempalte也好、还是用的WebClient也好,还是用的Feign也好,似乎跟我用不用Nacos没啥关系?我们在之前介绍Eureka和Consul的时候,也都是用同样的方法来实现服务调用的,不是吗?

确实是这样,对于Spring Cloud老手来说,就算我们更换了Nacos作为新的服务注册中心,其实对于我们应用层面的代码是没有影响的。那么为什么Spring Cloud可以带给我们这样的完美编码体验呢?实际上,这完全归功于Spring Cloud Common的封装,由于在服务注册与发现、客户端负载均衡等方面都做了很好的抽象,而上层应用方面依赖的都是这些抽象接口,而非针对某个具体中间件的实现。所以,在Spring Cloud中,我们可以很方便的去切换服务治理方面的中间件。

4.sentinel 流量监控、降级、熔断

下载对应的sentinel-dashboard的jar文件 启动即可 端口号为8080 登录账号密码都是sentinel

导入依赖和相关的配置

 <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-sentinel</artifactId>
  </dependency>


server:
  port: 8882
spring:
  application:
    name: cloudstudy-cunsumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719   #这是sentinel会创建一个HttpServer的端口号 默认8719 被占用则+1+1.... 当设置了一些规则后 传到这个server然后再注册到sentinel上

@ResourceSentinel
value 指定资源名 可自定义 一般与请求路径一直即可
fallback:失败调用,若本接口出现未知异常,则调用fallback指定的接口。
blockHandler:sentinel定义的失败调用或限制调用,若本次访问被限流或服务降级,则调用blockHandler指定的接口。
要注意指定的blockHandler方法与原本的方法 返回的参数要一致

(假设一个接口里抛出了异常 则会去执行对应的fallback方法 如果又在sentinal设置了限流等 则调用了几次后 返回blockhandler对应的方法)

blockHandlerClass 指定自定义全局的处理服务降级熔断后的返回方法 这样就不用一个方法又对应一个熔断方法

 @GetMapping("/get/{i}")
    @SentinelResource(value = "getI",blockHandler = "getI_Handler")
    public String getI(@PathVariable("i") Integer i) throws InterruptedException {
   
        //地址 返回值类型 参数在地址后面用数字表示 对应后面的可变长参数
        return String.valueOf(restTemplate.getForObject(PROVIDERSERVICEURL+"/get/{1}",Integer.class,i));
    }

    public String getI_Handler(Integer i,BlockException e){
   
        return "使用Sentinel实现服务降级";
        
    }

image-20201219001101759

控制台页面如上所示

当启动项目后 需要先访问一次端口号 才会在控制台有显示

可以看到有流控、降级、热点

流控是可以直接指定一个qps阈值 超过的话 则会去调用blockhandler对应的方法进行返回

降级是定义一个规则 例如RT(响应时间)超过多久就会进行降级 然后进行熔断一段时间(如下图中的时间窗口) 调用blockhandler

热点就是可以设立某个资源当传入某些某个参数时会进行降级 参数下标从0开始

image-20201219001537064

image-20201219001551153

image-20201219001601187

每次重启服务时,配置的各种规则都是消失,所以需要做规则的持久化

    <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值