20211027

Sentinel限流熔断应用实践

idea连接nacos

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51LXMZlF-1635341419470)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211027090456692.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vc2rW4Fy-1635341419477)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211027090520621.png)]

9:44;

package com.cy;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


/**
 * 课后练习:基于ScheduledExecutorService对象完成一个
 * 多线程任务的调度,在nacos注册中心发送定时心跳
 * 以及nacos配置中心数据定时拉取(pull)
 */
public class ScheduledExecutorServiceUtils {
    public static void main(String[] args) {


    //构建一个负责任务调度的线程池对象,池中最多三个线程;
    ScheduledExecutorService ses =
            Executors.newScheduledThreadPool(3);
    //构建任务对象
    Runnable take = new Runnable() {
        @Override
        public void run() {
            String tName = Thread.currentThread().getName();
            System.out.println(tName+"->"+System.currentTimeMillis());
        }
    };
    //执行任务调度(定时任务调度):1秒后开始执行,每隔5秒执行一次
    ses.scheduleAtFixedRate(take,
            1,//初始延迟
            5,//每隔5秒执行一次(与任务是否执行无关)
            TimeUnit.SECONDS);//时间单位

    }
}

一、读写锁简介

现实中有这样一种场景:对共享资源有读和写的操作,且写操作没有读操作那么频繁。在没有写操作的时候,多个线程同时读一个资源没有任何问题,所以应该允许多个线程同时读取共享资源;但是如果一个线程想去写这些共享资源,就不应该允许其他线程对该资源进行读和写的操作了。

ConcurrentHashMap,线程安全map,查;独占锁,排它锁;锁商场试衣间;

package com.jt.common.thread;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 简易服务注册中心测试(基于此,思考Nacos中服务的注册和发现)
 * 1)测试服务的注册
 * 2)测试服务的发现
 */
public class RegistryTests {
    //存储服务信息的容器(可以简单理解为nacos中存储服务信息的对象)
    private static Map<String,String> registryMap=new HashMap<>();
    //private static Map<String,String> registryMap=new ConcurrentHashMap<>();
    //读写锁,悲观写,乐观读 Segment对象守护--分段锁
    private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();//悲观写对象
    //服务的注册,将服务信息存储到map
    public  static void doRegist(String serviceId,String host){//悲观写
            readWriteLock.writeLock().lock();
        try {
            registryMap.put(serviceId, host);
        }finally {
            readWriteLock.writeLock().unlock();
        }
    }
    //服务的发现,从map中基于key获取服务实例
    public  static String doLookup(String serviceId){//乐观读
            readWriteLock.readLock().lock();
        try {
            return registryMap.get(serviceId);
        }finally {
            readWriteLock.readLock().unlock();
        }
    }
    public static void main(String[] args) {
        //1.构建服务名,服务地址,服务名与服务地址有一一对应关系
        //1.1服务名
        String[] serviceIds=new String[100];
        //1.2服务地址
        String[] hostIds=new String[100];
        //1.3数据初始化
        for(int i=0;i<100;i++){
             serviceIds[i]="Serivce-"+i;
             hostIds[i]="Host-"+i;
        }
        //2.构建线程对象,模拟服务注册和发现
        Thread t1=new Thread(){
            @Override
            public void run() {
                for(int i=0;i<25;i++){
                    doRegist(serviceIds[i],hostIds[i]);
                }
            }
        };
        Thread t2=new Thread(){
            @Override
            public void run() {
                for(int i=25;i<50;i++){
                    doRegist(serviceIds[i],hostIds[i]);
                }
            }
        };
        Thread t3=new Thread(){
            @Override
            public void run() {
                for(int i=50;i<75;i++){
                    doRegist(serviceIds[i],hostIds[i]);
                }
            }
        };
        Thread t4=new Thread(){
            @Override
            public void run() {
                for(int i=75;i<100;i++){
                    doRegist(serviceIds[i],hostIds[i]);
                }
            }
        };
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        //2.构建线程对象,模拟服务注册和发现



    }
}

ReentrantReadWriteLock读写锁详解

1.jar包下载地址

https://github.com/alibaba/Sentinel/releases

2.启动命令

java -Dserver.port=8180 -Dcsp.sentinel.dashboard.server=localhost:8180 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.0.jar

Sentinel限流入门

添加jar包

<!--        添加Sentinel依赖,添加此依赖以后,会在项目中添加一个拦截器对象,这个对象会此服务发出的请求,
             进行拦截,拦截到请求以后会与Sentinel控制台定义的限流规则进行比对,假如在允许范围对,则继续访问,
             否则进行限流或者降级操作-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

服务提供方添加配置

spring:
  cloud:
    sentinel:
      transport:
         dashboard: localhost:8180 # 指定sentinel控制台地址。

创建一个用于演示限流操作的Controller对象,例如:

package com.cy.provider.Controller;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/provider")
public class ProviderSentinelController {
    @GetMapping("/sentinel01")
    public String doSentinel01(){
        return "sentinel 01 test  ...";
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9vyWNHp8-1635341419482)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211027150002615.png)]

设置限流模式

Sentinel的流控模式代表的流控的方式,默认【直接】,还有关联,链路。

直接模式

Sentinel默认的流控处理就是【直接->快速失败】。

关联模式

当关联的资源达到阈值,就限流自己。例如设置了关联资源为/ur2时,假如关联资源/url2的qps阀值超过1时,就限流/url1接口(是不是感觉很霸道,关联资源达到阀值,是本资源接口被限流了)。这种关联模式有什么应用场景呢?我们举个例子,订单服务中会有2个重要的接口,一个是读取订单信息接口,一个是写入订单信息接口。在高并发业务场景中,两个接口都会占用资源,如果读取接口访问过大,就会影响写入接口的性能。业务中如果我们希望写入订单比较重要,要优先考虑写入订单接口。那就可以利用关联模式;在关联资源上面设置写入接口,资源名设置读取接口就行了;这样就起到了优先写入,一旦写入请求多,就限制读的请求。例如

第一步:在ProviderSentinelController中添加一个方法,例如:

 @GetMapping("/sentinel02")
   public String doSentinel02(){
     return "sentinel 02 test  ...";
   }

https://jmeter.apache.org/changes.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值