02、sentinel - 限流实例

我们已经知道了 Sentinel 的三大功能:限流 降级 系统保护。现在让我们来了解下具体的使用方法,以限流来演示具体的步骤。

引入依赖

首先肯定是要先引入需要的依赖,如下所示:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-core</artifactId>
    <version>x.y.z</version>
</dependency>

这里的版本号 x.y.z 可以根据需要自行选择,我选择的是截至目前为止的最新版:1.4.0。

定义资源

假设我们有一个 UserService :

public class UserService {
    /**
     * 根据uid获取用户信息
     * @param uid uid
     * @return 用户信息
     */
    public User getUser(Long uid){
        // 业务代码
        User user = new User();
        user.setUid(uid);
        user.setName("user-" + uid);
        return user;
    }

    public static class User {
        private Long uid;
        private String name;
        // 省略getter、setter
    }
}

现在我们要对 getUser 方法进行限流,那首先我们要定义一个资源,在 sentinel 中资源是抽象出来做具体的操作的,用资源来保护我们的代码和服务。

用户只需要为受保护的代码或服务定义一个资源,然后定义规则就可以了,剩下的都交给sentinel来处理了。定义完资源后,就可以通过在程序中埋点来保护你自己的服务了,埋点的方式有两种:抛出异常和返回布尔值。

下面我用抛出异常的方式进行埋点:

// 定义的资源
public static final String USER_RES = "userResource";

public User getUser(Long uid){
    Entry entry = null;
    try {
        // 流控代码
        entry = SphU.entry(USER_RES);
        // 业务代码
        User user = new User();
        user.setUid(uid);
        user.setName("user-" + uid);
        return user;
    }catch(BlockException e){
        // 被限流了
        System.out.println("[getUser] has been protected! Time="+System.currentTimeMillis());
    }finally {
        if(entry!=null){
            entry.exit();
        }
    }
    return null;
}

除了通过抛出异常的方式定义资源外,返回布尔值的方式也是一样的,这里不具体展开了。

PS:如果你不想对原有的业务代码进行侵入,也可以通过注解 SentinelResource 来进行资源埋点。

定义规则

定义完资源后,就可以来定义限流的规则了,但是我们需要对流控规则做个详细的了解,以便更好的进行限流的操作,流控的规则对应的是 FlowRule。