前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >解读JVM级别本地缓存Caffeine青出于蓝的要诀2 —— 弄清楚Caffeine的同步、异步回源方式

解读JVM级别本地缓存Caffeine青出于蓝的要诀2 —— 弄清楚Caffeine的同步、异步回源方式

原创
作者头像
是Vzn呀
发布于 2022-12-13 01:16:29
发布于 2022-12-13 01:16:29
8290
举报
文章被收录于专栏:架构悟道架构悟道

大家好,又见面了。

本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面。如果感兴趣,欢迎关注以获取后续更新。

上一篇文章中,我们继Guava Cache之后,又认识了青出于蓝的Caffeine。作为一种对外提供黑盒缓存能力的专门组件,Caffeine基于穿透型缓存模式进行构建。也即对外提供数据查询接口,会优先在缓存中进行查询,若命中缓存则返回结果,未命中则尝试去真正的源端(如:数据库)去获取数据并回填到缓存中,返回给调用方。

与Guava Cache相似,Caffeine回源填充主要有两种手段:

  • Callable方式
  • CacheLoader方式

根据执行调用方式不同,又可以细分为同步阻塞方式与异步非阻塞方式。

本文我们就一起探寻下Caffeine的多种不同的数据回源方式,以及对应的实际使用。

同步方式

同步方式是最常被使用的一种形式。查询缓存、数据回源、数据回填缓存、返回执行结果等一系列操作都是在一个调用线程中同步阻塞完成的。

Callable

在每次get请求的时候,传入一个Callable函数式接口具体实现,当没有命中缓存的时候,Caffeine框架会执行给定的Callable实现逻辑,去获取真实的数据并且回填到缓存中,然后返回给调用方。

代码语言:java
AI代码解释
复制
public static void main(String[] args) {
    Cache<String, User> cache = Caffeine.newBuilder().build();
    User user = cache.get("123", s -> userDao.getUser(s));
    System.out.println(user);
}

Callable方式的回源填充,有个明显的优势就是调用方可以根据自己的场景,灵活的给定不同的回源执行逻辑。但是这样也会带来一个问题,就是如果需要获取缓存的地方太多,会导致每个调用的地方都得指定下对应Callable回源方法,调用起来比较麻烦,且对于需要保证回源逻辑统一的场景管控能力不够强势,无法约束所有的调用方使用相同的回源逻辑。

这种时候,便需要CacheLoader登场了。

CacheLoader

在创建缓存对象的时候,可以通在build()方法中传入指定的CacheLoader对象的方式来指定回源时默认使用的回源数据加载器,这样当使用方调用get方法获取不到数据的时候,框架就会自动使用给定的CacheLoader对象执行对应的数据加载逻辑。

比如下面的代码中,便在创建缓存对象时指定了当缓存未命中时通过userDao.getUser()方法去DB中执行数据查询操作:

代码语言:java
AI代码解释
复制
public LoadingCache<String, User> createUserCache() {
    return Caffeine.newBuilder()
            .maximumSize(10000L)
            .build(key -> userDao.getUser(key));
}

相比于Callable方式,CacheLoader更适用所有回源场景使用的回源策略都固定且统一的情况。对具体业务使用的时候更加的友好,调用get方法也更加简单,只需要传入带查询的key值即可。

上面的示例代码中还有个需要关注的点,即创建缓存对象的时候指定了CacheLoader,最终创建出来的缓存对象是LoadingCache类型,这个类型是Cache的一个子类,扩展提供了无需传入Callable参数的get方法。进一步地,我们打印出对应的详细类名,会发现得到的缓存对象具体类型为:

代码语言:txt
AI代码解释
复制
com.github.benmanes.caffeine.cache.BoundedLocalCache.BoundedLocalLoadingCache

当然,如果创建缓存对象的时候没有指定最大容量限制,则创建出来的缓存对象还可能会是下面这个:

代码语言:txt
AI代码解释
复制
com.github.benmanes.caffeine.cache.UnboundedLocalCache.UnboundedLocalManualCache

通过UML图,可以清晰的看出其与Cache之间的继承与实现链路情况:

因为LoadingCache是Cache对象的子类,根据JAVA中类继承的特性,LoadingCache也完全具备Cache所有的接口能力。所以,对于大部分场景都需要固定且统一的回源方式,但是某些特殊场景需要自定义回源逻辑的情况,也可以通过组合使用Callable的方式来实现。

比如下面这段代码:

代码语言:java
AI代码解释
复制
public static void main(String[] args) {
    LoadingCache<String, User> cache = Caffeine.newBuilder().build(userId -> userDao.getUser(userId));
    // 使用CacheLoader回源
    User user = cache.get("123");
    System.out.println(user);
    // 使用自定义Callable回源
    User techUser = cache.get("J234", userId -> {
        // 仅J开头的用户ID才会去回源
        if (!StringUtils.isEmpty(userId) && userId.startsWith("J")) {
            return userDao.getUser(userId);
        } else {
            return null;
        }
    });
    System.out.println(techUser);
}

上述代码中,构造的是一个指定了CacheLoader的LoadingCache缓存类型,这样对于大众场景可以直接使用get方法由CacheLoader提供统一的回源能力,而特殊场景中也可以在get方法中传入需要的定制化回源Callable逻辑。

不回源

在实际的缓存应用场景中,并非是所有的场景都要求缓存没有命中的时候要去执行回源查询。对于一些业务规划上无需执行回源操作的请求,也可以要求Caffeine不要执行回源操作(比如黑名单列表,只要用户在黑名单就禁止操作,不在黑名单则允许继续往后操作,因为大部分请求都不会命中到黑名单中,所以不需要执行回源操作)。为了实现这一点,在查询操作的时候,可以使用Caffeine提供的免回源查询方法来实现。

具体梳理如下:

接口

功能说明

getIfPresent

从内存中查询,如果存在则返回对应值,不存在则返回null

getAllPresent

批量从内存中查询,如果存在则返回存在的键值对,不存在的key则不出现在结果集里

代码使用演示如下:

代码语言:java
AI代码解释
复制
public static void main(String[] args) {
    LoadingCache<String, User> cache = Caffeine.newBuilder().build(userId -> userDao.getUser(userId));
    cache.put("124", new User("124", "张三"));
    User userInfo = cache.getIfPresent("123");
    System.out.println(userInfo);
    Map<String, User> presentUsers =
            cache.getAllPresent(Stream.of("123", "124", "125").collect(Collectors.toList()));
    System.out.println(presentUsers);
}

执行结果如下,可以发现执行的过程中并没有触发自动回源与回填操作:

代码语言:txt
AI代码解释
复制
null
{124=User(userName=张三, userId=124)}

异步方式

CompletableFuture并行流水线能力,是JAVA8异步编程领域的一个重大改进。可以将一系列耗时且无依赖的操作改为并行同步处理,并等待各自处理结果完成后继续进行后续环节的处理,由此来降低阻塞等待时间,进而达到降低请求链路时长的效果。

很多小伙伴对JAVA8之后的CompletableFuture并行处理能力接触的不是很多,有兴趣的可以移步看下我之前专门介绍JAVA8流水线并行处理能力的介绍《JAVA基于CompletableFuture的流水线并行处理深度实践,满满干货》,相信可以让你对ComparableFututre并行编程有全面的认识与理解。

Caffeine完美的支持了在异步场景下的流水线处理使用场景,回源操作也支持异步的方式来完成。

异步Callable

要想支持异步场景下使用缓存,则创建的时候必须要创建一个异步缓存类型,可以通过buildAsync()方法来构建一个AsyncCache类型缓存对象,进而可以在异步场景下进行使用。

看下面这段代码:

代码语言:java
AI代码解释
复制
public static void main(String[] args) {
    AsyncCache<String, User> asyncCache = Caffeine.newBuilder().buildAsyn();
    CompletableFuture<User> userCompletableFuture = asyncCache.get("123", s -> userDao.getUser(s));
    System.out.println(userCompletableFuture.join());
}

上述代码中,get方法传入了Callable回源逻辑,然后会开始异步的加载处理操作,并返回了个CompletableFuture类型结果,最后如果需要获取其实际结果的时候,需要等待其异步执行完成然后获取到最终结果(通过上述代码中的join()方法等待并获取结果)。

我们可以比对下同步异步两种方式下Callable逻辑执行线程情况。看下面的代码:

代码语言:java
AI代码解释
复制
public static void main(String[] args) {
    System.out.println("main thread:" + Thread.currentThread().getId());
    // 同步方式
    Cache<String, User> cache = Caffeine.newBuilder().build();
    cache.get("123", s -> {
        System.out.println("同步callable thread:" + Thread.currentThread().getId());
        return userDao.getUser(s);
    });
    // 异步方式
    AsyncCache<String, User> asyncCache = Caffeine.newBuilder().buildAsync();
    asyncCache.get("123", s -> {
        System.out.println("异步callable thread:" + Thread.currentThread().getId());
        return userDao.getUser(s);
    });
}

执行结果如下:

代码语言:txt
AI代码解释
复制
main thread:1
同步callable thread:1
异步callable thread:15

结果很明显的可以看出,同步处理逻辑中,回源操作直接占用的调用线程进行操作,而异步处理时则是单独线程负责回源处理、不会阻塞调用线程的执行 —— 这也是异步处理的优势所在。

看到这里,也许会有小伙伴有疑问,虽然是异步执行的回源操作,但是最后还是要在调用线程里面阻塞等待异步执行结果的完成,似乎没有看出异步有啥优势?

异步处理的魅力,在于当一个耗时操作执行的同时,主线程可以继续去处理其它的事情,然后其余事务处理完成后,直接去取异步执行的结果然后继续往后处理。如果主线程无需执行其余处理逻辑,完全是阻塞等待异步线程加载完成,这种情况确实没有必要使用异步处理。

想象一个生活中的场景:

周末休息的你出去逛街,去咖啡店点了一杯咖啡,然后服务员会给你一个订单小票。 当服务员在后台制作咖啡的时候,你并没有在店里等待,而是出门到隔壁甜品店又买了个面包。 当面包买好之后,你回到咖啡店,拿着订单小票去取咖啡。 取到咖啡后,你边喝咖啡边把面包吃了……嗝~

这种情况应该比较好理解了吧?如果是同步处理,你买咖啡的时候,需要在咖啡店一直等到咖啡做好然后才能再去甜品店买面包,这样耗时就比较长了。而采用异步处理的策略,你在等待咖啡制作的时候,继续去甜品店将面包买了,然后回来等待咖啡完成,这样整体的时间就缩短了。当然,如果你只想买个咖啡,也不需要买甜品面包,即你等待咖啡制作期间没有别的事情需要处理,那这时候你在不在咖啡店一直等到咖啡完成,都没有区别。

回到代码层面,下面代码演示了异步场景下AsyncCache的使用。

代码语言:java
AI代码解释
复制
public boolean isDevUser(String userId) {
    // 获取用户信息
    CompletableFuture<User> userFuture = asyncCache.get(userId, s -> userDao.getUser(s));
    // 获取公司研发体系部门列表
    CompletableFuture<List<String>> devDeptFuture =
            CompletableFuture.supplyAsync(() -> departmentDao.getDevDepartments());
    // 等用户信息、研发部门列表都拉取完成后,判断用户是否属于研发体系
    CompletableFuture<Boolean> combineResult =
            userFuture.thenCombine(devDeptFuture,
                    (user, devDepts) -> devDepts.contains(user.getDepartmentId()));
    // 等待执行完成,调用线程获取最终结果
    return combineResult.join();
}

在上述代码中,需要获取到用户详情与研发部门列表信息,然后判断用户对应的部门是否属于研发部门,从而判断员工是否为研发人员。整体采用异步编程的思路,并使用了Caffeine异步缓存的操作方式,实现了用户获取与研发部门列表获取这两个耗时操作并行的处理,提升整体处理效率。

异步CacheLoader

异步处理的时候,Caffeine也支持直接在创建的时候指定CacheLoader对象,然后生成支持异步回源操作的AsyncLoadingCache缓存对象,然后在使用get方法获取结果的时候,也是返回的CompletableFuture异步封装类型,满足在异步编程场景下的使用。

代码语言:java
AI代码解释
复制
public static void main(String[] args) {
    try {
        AsyncLoadingCache<String, User> asyncLoadingCache =
                Caffeine.newBuilder().maximumSize(1000L).buildAsync(key -> userDao.getUser(key));
        CompletableFuture<User> userCompletableFuture = asyncLoadingCache.get("123");
        System.out.println(userCompletableFuture.join());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

异步AsyncCacheLoader

除了上述这种方式,在创建的时候给定一个用于回源处理的CacheLoader之外,Caffeine还有一个buildAsync的重载版本,允许传入一个同样是支持异步并行处理的AsyncCacheLoader对象。使用方式如下:

代码语言:java
AI代码解释
复制
public static void main(String[] args) {
    try {
        AsyncLoadingCache<String, User> asyncLoadingCache =
                Caffeine.newBuilder().maximumSize(1000L).buildAsync(
                        (key, executor) -> CompletableFuture.supplyAsync(() -> userDao.getUser(key), executor)
                );
        CompletableFuture<User> userCompletableFuture = asyncLoadingCache.get("123");
        System.out.println(userCompletableFuture.join());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

与上一章节中的代码比对可以发现,不管是使用CacheLoader还是AsyncCacheLoader对象,最终生成的缓存类型都是AsyncLoadingCache类型,使用的时候也并没有实质性的差异,两种方式的差异点仅在于传入buildAsync方法中的对象类型不同而已,使用的时候可以根据喜好自行选择。

进一步地,如果我们尝试将上面代码中的asyncLoadingCache缓存对象的具体类型打印出来,我们会发现其具体类型可能是:

代码语言:txt
AI代码解释
复制
com.github.benmanes.caffeine.cache.BoundedLocalCache.BoundedLocalAsyncLoadingCache

而如果我们在构造缓存对象的时候没有限制其最大容量信息,其构建出来的缓存对象类型还可能会是下面这个:

代码语言:txt
AI代码解释
复制
com.github.benmanes.caffeine.cache.UnboundedLocalCache.UnboundedLocalAsyncLoadingCache

与前面同步方式一样,我们也可以看下这两个具体的缓存类型对应的UML类图关系:

可以看出,异步缓存不同类型最终都实现了同一个AsyncCache顶层接口类,而AsyncLoadingCache作为继承自AsyncCache的子类,除具备了AsyncCache的所有接口外,还额外扩展了部分的接口,以支持未命中目标时自动使用指定的CacheLoader或者AysncCacheLoader对象去执行回源逻辑。

小结回顾

好啦,关于Caffeine Cache的同步、异步数据回源操作原理与使用方式的阐述,就介绍到这里了。不知道小伙伴们是否对Caffeine Cache的回源机制有了全新的认识了呢?而关于Caffeine Cache,你是否有自己的一些想法与见解呢?欢迎评论区一起交流下,期待和各位小伙伴们一起切磋、共同成长。

下一篇文章中,我们将深入讲解下Caffeine改良过的异步数据驱逐处理实现,以及Caffeine支持的多种不同的数据淘汰驱逐机制和对应的实际使用。如有兴趣,欢迎关注后续更新。

📣 补充说明1

本文属于《深入理解缓存原理与实战设计》系列专栏的内容之一。该专栏围绕缓存这个宏大命题进行展开阐述,全方位、系统性地深度剖析各种缓存实现策略与原理、以及缓存的各种用法、各种问题应对策略,并一起探讨下缓存设计的哲学。如果有兴趣,也欢迎关注此专栏。

📣 补充说明2

我是悟道,聊技术、又不仅仅聊技术~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
HTTPS证书申请及windows server部署
StartSSL免费DV证书 沃通(Wosign)免费DV证书 这两个已经被苹果拉入黑名单。我10月份在StartSSL申请的证书还可以使用。但是近期申请的已经不被信任,苹果设备上使用近期申请的证书都已经无法打开(亲测)。 如果证书无效或不被信任在微信企业号里面打开的时候会提示 网络出错,请轻触重新加载 -1202的提示。 -1202的错误的意思就是kCFURLErrorServerCertificateUntrusted
forrest23
2018/08/03
3.2K0
Let's Encrypt免费泛域名SSL证书申请及自动续签
Let's Encrypt: https://letsencrypt.org , 是一个免费的、自动化的、开放的证书颁发机构。截至2018年9月,它的全球SSL证书市场份额已超过50%,得到主流浏览器和厂商的认可与支持。
Cong Min
2019/09/07
21K1
Windows Server 下 IIS 申请部署 Let’s Encrypt 证书实现 HTTPS
在明月有关 Let's Encrypt 证书申请部署的文章里如:【Linux 下使用 acme.sh 申请和管理 Let’s Encrypt 证书】、【一年多 Let’s Encrypt 的 SSL 证书使用有感】、【Let’s Encrypt 证书站点在又拍云 CDN 下如何实现自动续期?】等都是依托于 LNMP 生产环境的, Windows Server 下的 IIS 下申请部署 Let's Encrypt 的好像一直缺失,很明显这不科学!今天明月就分享给大家一个 Windows Server 上 IIS 下申请部署 Let's Encrypt 的方法。
明月登楼的博客
2019/05/15
3.7K0
Windows Server 下 IIS 申请部署 Let’s Encrypt 证书实现 HTTPS
Certbot实现自动签发及续签Let's Encrypt免费SSL证书
由于目前免费SSL证书有效期通常只有90天,在到期前需要手动申请、部署证书较为麻烦,甚至会因为未及时续签证书导致网址无法访问。
参谋带个长
2024/09/19
6920
【译】Let’s Encrypt – 免费的SSL/TLS证书
每一个建立过安全站点的人都在如何维护证书这个问题上深受困扰。Let’s Encrypt 推荐的客户端 Certbot,能够自动的消除这些用户的痛点,并且让站点维护人员能够使用简单的命令开启和管理站点的HTTPS功能。
用户2131907
2019/02/27
1.1K0
使用Certify来自动申请并配置Let’s Encrypt免费SSL证书到IIS8
越来越多的网站在启用HTTPS,也就是SSL加密通讯连接访问。特别是去年开始BAT在国内的推广和应用要求。要知道部署发布一个苹果iOS企业应用,下载服务器就必须使用HTTPS协议。
崔文远TroyCui
2019/02/26
2.9K0
使用Certify来自动申请并配置Let’s Encrypt免费SSL证书到IIS8
了解 SSL 证书类型,没有所谓的“品质”和“等级”之分
很多站长们很好奇为什么 SSL 证书有免费版的、有收费版的、有些收费版的价格非常的高昂,其实这主要是因为 SSL 证书的类型不同而已,确切的说只有三种不同的类型,分别是 DV SSL、OV SSL、EV SSL,不同的类型针对不同类型的网站域名和行业需求而定的。所以说 SSL 证书没有所谓的“品质”和“等级”之分,只有三种不同的类型。
明月登楼的博客
2019/05/15
7690
了解 SSL 证书类型,没有所谓的“品质”和“等级”之分
白嫖https免费证书
HTTPS 证书的定价因供应商、证书类型、证书品牌、有效期等因素而异。一般来说,SSL/TLS 证书的价格分为以下几种类型:
叔牙
2023/06/21
1.1K0
白嫖https免费证书
DV,OV,EV证书优势区别
互联网在国内最近20年的发展,使得网民数量迅速增长,很多用户在访问网站时,对使用HTTP协议已经习以为常,但随着时代的发展,网络技术的革新也是日新月异,HTTPS协议的诞生满足了用户对网站安全的需求,并且正日益成为网络安全领域的潮流和新趋势。
JoySSL
2023/02/03
1.6K0
DV,OV,EV证书优势区别
快速配置Let's encrypt通配符证书
利用certbot工具配置Let’s encrypt通配符证书,所域名下所有的子域名都能方便的使用 https证书,而且完全免费。值得关注的是,Let’s encrypt通配符证书只是针对二级域名,并不能针对主域名,如*.hubinqiang.com和hubinqiang.com 被认为是两个域名,如果和我一样使用的是主域名,在申请的时候需要注意都要申请。
OwenZhang
2021/12/08
2.2K0
快速配置Let's encrypt通配符证书
手把手教你免费申请支持通配符的 SSL 证书
得益于 Google 等大厂的消灭 HTTP 运动和 Let’s Encrypt 非盈利组织的努力,越来越多的站点开始迁移到 HTTPS,下图是 Let’s Encrypt 的统计数据。
iMike
2019/07/30
7K0
获取 Let's Encrypt 免费通配符证书实现Https
说明 3月14日,Let's Encrypt的执行董事Josh Aas对外宣布,他们的通配符证书正式上线,用户可以基于此特性轻松部署/开启所有子域名的HTTPS功能。 Let's Encrypt 是国外一个公共的免费SSL项目,由 Linux 基金会托管,它的来头不小,由 Mozilla、思科、Akamai、IdenTrust 和 EFF 等组织发起,目的就是向网站自动签发和管理免费证书,以便加速互联网由 HTTP 过渡到 HTTPS,目前 Facebook 等大公司开始加入赞助行列。 Let's Encr
晓晨
2018/06/22
2.6K0
获取Let's Encrypt免费TLS/SSL证书的那点事儿
Let's Encrypt是一个于2015年三季度推出的数字证书认证机构,旨在以自动化流程消除手动创建和安装证书的复杂流程,并推广使万维网服务器的加密连接无所不在,为安全网站提供免费的SSL/TLS证书。 -- 引自维基百科
用户1456517
2019/03/05
1.6K0
使用Let's Encrypt -- 免费的https证书
老高的证书快过期了(2016-12-11),本着节约资(R)源(MB)的精神,准备使用Let's Encrypt。
老高的技术博客
2022/12/27
1.2K0
使用Let's Encrypt  -- 免费的https证书
HTTPS证书知识扫盲
现在搞网站域名不加个HTTPS就显得不专业,特别在使用JWT进行认证的接口一定要加HTTPS为你的接口增加一层安全屏障。今天就来聊聊配置HTTPS的关键SSL证书,也被称为CA证书。
码农小胖哥
2020/09/28
1.7K0
使用Let's Encrypt的SSL证书配置HTTPS手记
前段时间,看见很多大会都在分享全站HTTPS的经验。HTTPS固然好,前提是SSL证书,并且签发证书的机构要靠谱。沃通的CA证书就相继被Mozilla和Google封杀了。曾经对于普通用户,权威,安全,并且免费的证书无疑就像天上的星星,可望而不可及。现在,这些星星变成了馅饼掉了下来。没错,我们可以申请安全免费的ssl证书--- Let's Encrypt。 Let’s Encrypt是电子前哨基金会(EFF)发布的免费 SSL 证书服务,Google,Mozilla和Microsoft都极力支持。很早之前就
李海彬
2018/03/19
2.5K0
使用Let's Encrypt的SSL证书配置HTTPS手记
Linux 下 Nginx 安装部署 Let’s Encrypt 证书实现 HTTPS
网站转成https是大势所趋。但是在国内,推进的过程显然要比国外慢很多。现阶段如果将自己的网站改成https以后,会碰到这样的尴尬现象:如果在页面上引用了http://的链接或者图片,用户在浏览器上会看到类似该网站是非安全网站的警告,对于网站运营者来说可以说非常冤。由于很多链接是第三方的,没有办法去控制。
星哥玩云
2022/07/14
3.4K0
Linux  下 Nginx 安装部署 Let’s Encrypt 证书实现 HTTPS
Windows Ubuntu Bash申请免费通配符证书(Let’s Encrypt)并绑定IIS
部署 HTTPS 网站的时候需要证书,证书由 CA 机构签发,大部分传统 CA 机构签发证书是需要收费的,这不利于推动 HTTPS 协议的使用。
星哥玩云
2022/07/13
1.7K0
Windows Ubuntu Bash申请免费通配符证书(Let’s Encrypt)并绑定IIS
Let’s Encrypt 官方推荐 Certbot 工具快速部署 SSL 证书
Let’s Encrypt免费 SSL 证书已经受到了包括 FireFox、Chrome 在内的众多主流浏览器的兼容和支持,目前国内的应用主要是提现在各大电商网站和门户网站上,可以提高访问和交易安全性。很多外贸公司网站也使用是因为 google 已经明确表示有提供 SSL 证书将会是一个加分因素。那么对于我们广大站长来说,也许将来某一天你的网站就需要添加这么一个 SSL 证书。 给网站添加 SSL 证书的方式有很多,老魏以后会分别写教程。今天魏艾斯博客(www.vpsss.net)说一下Let’s Encr
魏艾斯博客www.vpsss.net
2018/06/01
2.2K0
SSL证书为什么要选付费?
SSL证书已经越来越多的使用在网站,小程序和APP上,对于保障网络安全,加密数据信息有至关重要的作用。随着SSL证书市场的发展,各种类型的证书产品也在不断丰富,用户在选择SSL证书时,除了可以购买付费证书,也可以在部分证书平台申请免费SSL证书。
JoySSL
2023/02/20
1.6K0
SSL证书为什么要选付费?
推荐阅读
相关推荐
HTTPS证书申请及windows server部署
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档