SpringCloud Alibaba 快速入门

253 阅读2分钟

这是我参与8月更文挑战的第12天,活动详情查看:8月更文挑战

创建父工程

Spring Cloud Alibaba 的环境在父工程中创建,微服务的各个组件作为子工程,继承父工程的环境。

Spring Boot ---》Spring Cloud ---》Spring Cloud Alibaba

pom.xml 中添加。

<dependencyManagement>
    <dependencies>
        <!-- Spring Cloud Hoxton -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <!-- Spring Cloud Alibaba -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Nacos 服务注册

nacos官方手册 :nacos.io/zh-cn/docs/…

选择你需要的版本下载,解压,启动服务,下载地址: github.com/alibaba/nac…

Nacos 搭建成功,接下来注册服务。

在父工程路径下创建子工程,让子工程继承父工程的环境依赖,pom.xml 中添加 nacos 发现组件。

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

application.yml 中配置

spring:
  cloud:
    nacos:
      discovery:
        # 指定nacos server地址
        server-addr: localhost:8848
  application:
    name: my-nacos

Nacos 服务发现与调用

pom.xml 添加 discovery,完成服务发现。

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

通过 discoveryClient 发现注册到 nacos 中的 provider 服务。

@RestController
public class ConsumerController {
​
    @Autowired
    private DiscoveryClient discoveryClient;
​
    @GetMapping("/instances")
    public List<ServiceInstance> instances(){
        List<ServiceInstance> provider = discoveryClient.getInstances("provider");
        return provider;
    }
​
}
@Configuration
public class ConsumerConfig {
​
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
​
}
@RestController
public class ConsumerController {
​
    @Autowired
    private DiscoveryClient discoveryClient;
    @Autowired
    private RestTemplate restTemplate;
​
    @GetMapping("/index")
    public String index(){
        List<ServiceInstance> provider = discoveryClient.getInstances("provider");
        int index = ThreadLocalRandom.current().nextInt(provider.size());
        String url = provider.get(index).getUri()+"/index";
        return "consumer随机远程调用provier:"+this.restTemplate.getForObject(url, String.class);
    }
​
}

Ribbon 负载均衡

ribbon 是一个客户端负载均衡器,可以简单的理解成类似于 nginx的负载均衡模块的功能。

Load Balance负载均衡是用于解决一台机器(一个进程)无法解决所有请求而产生的一种算法。像nginx可以使用负载均衡分配流量,ribbon为客户端提供负载均衡,dubbo服务调用里的负载均衡等等,很多地方都使用到了负载均衡。

@Configuration
public class ConsumerConfig {
​
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
​
}
@RestController
public class ConsumerController {
​
    @Autowired
    private RestTemplate restTemplate;
​
    @GetMapping("/index")
    public String index(){
        return "consumer远程调用provier:"+this.restTemplate.getForObject("http://provider/index", String.class);
    }
​
}

随机

server:
  port: 8180
provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

Nacos 权重

@Slf4j
public class NacosWeightedRule extends AbstractLoadBalancerRule {
​
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;
​
    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
        //读取配置文件
    }
​
    @Override
    public Server choose(Object o) {
        ILoadBalancer loadBalancer = this.getLoadBalancer();
        BaseLoadBalancer baseLoadBalancer = (BaseLoadBalancer) loadBalancer;
        //获取要请求的微服务名称
        String name = baseLoadBalancer.getName();
        //获取服务发现的相关API
        NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
        try {
            Instance instance = namingService.selectOneHealthyInstance(name);
            log.info("选择的实例是port={},instance={}",instance.getPort(),instance);
            return new NacosServer(instance);
        } catch (NacosException e) {
            e.printStackTrace();
            return null;
        }
    }
}
server:
  port: 8180
provider:
  ribbon:
    NFLoadBalancerRuleClassName: com.southwind.configuration.NacosWeightedRule

Sentinel 服务限流降级

雪崩效应

解决方案

1、设置线程超时

2、设置限流

3、熔断器 Sentinel、Hystrix

1、pom.xml 引入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency><dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2、application 配置

management:
  endpoints:
    web:
      exposure:
        include: '*'
spring:
  cloud:
    sentinel:
      transport:
        dashboard: localhost:8080

3、下载 Sentinel 控制台,解压,启动。

流控规则

直接限流

关联限流

链路限流

1、pom.xml 添加依赖

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>1.7.1</version>
</dependency><dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-web-servlet</artifactId>
    <version>1.7.1</version>
</dependency>

2、application.yml

spring:
    cloud:
        sentinel:
          filter:
            enabled: false

3、写配置类

package com.southwind.configuration;
​
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
​
@Configuration
public class FilterConfiguration {
​
    @Bean
    public FilterRegistrationBean registrationBean(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new CommonFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY,"false");
        registrationBean.setName("sentinelFilter");
        return registrationBean;
    }
}

4、Service

@Service
public class HelloService {
​
    @SentinelResource("test")
    public void test(){
        System.out.println("test");
    }
}

5、Controller

@GetMapping("/test1")
public String test1(){
    this.helloService.test();
    return "test1";
}
​
@GetMapping("/test2")
public String test2(){
    this.helloService.test();
    return "test2";
}