0%

1.jpeg

前言

Google 出的 Guava 是 Java 核心增强的库,应用非常广泛。

我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Google 大牛们是如何设计的。

缓存

本次主要讨论缓存。

缓存在日常开发中举足轻重,如果你的应用对某类数据有着较高的读取频次,并且改动较小时那就非常适合利用缓存来提高性能。

缓存之所以可以提高性能是因为它的读取效率很高,就像是 CPU 的 L1、L2、L3 缓存一样,级别越高相应的读取速度也会越快。

但也不是什么好处都占,读取速度快了但是它的内存更小资源更宝贵,所以我们应当缓存真正需要的数据。

其实也就是典型的空间换时间。

下面谈谈 Java 中所用到的缓存。

Read more »

前言

之前在做 秒杀架构实践 时有提到对 distributed-redis-tool 的一次小升级,但是没有细说。

其实主要原因是:

秒杀时我做压测:由于集成了这个限流组件,并发又比较大,所以导致连接、断开 Redis 非常频繁。
最终导致获取不了 Redis connection 的异常。

池化技术

这就是一个典型的对稀缺资源使用不善导致的。

何为稀缺资源?常见的有:

  • 线程
  • 数据库连接
  • 网络连接等

这些资源都有共同的特点:创建销毁成本较高

Read more »

2012/02/28

2012年二月二十八日。

这天学校举行了高考 100 天誓师大会,当时完全不知道意味着什么,只感觉现场热血沸腾、激情高涨,心里告诉自己就算只剩下 100 天我也能考上清华其次也是北大。

2012/06/03

2012年六月三日。

晚自习拿出前段时间刚拍的毕业合照,恨死摄影师,没有抓拍到我最帅的角度😡。

Read more »

photo-1522204657746-fccce0824cfd.jpeg

前言

Netty 是一个高性能的 NIO 网络框架,本文基于 SpringBoot 以常见的心跳机制来认识 Netty。

最终能达到的效果:

  • 客户端每隔 N 秒检测是否需要发送心跳。
  • 服务端也每隔 N 秒检测是否需要发送心跳。
  • 服务端可以主动 push 消息到客户端。
  • 基于 SpringBoot 监控,可以查看实时连接以及各种应用信息。

效果如下:

show

Read more »

alarm-clock-art-background-1037993.jpg

前言

首先标题党一下,其实这篇文章主要是记录我的第二个过 1K star 的项目 Java-Interview,顺便分享下其中的过程及经验。

4.png

需求选择

Java-Interview

之所以要做这个项目主要是当时我正在面阿里的两个部门,非常幸运的是技术面都过了。其中的过程真是让我受益匪浅更是印象深刻,所以就想把期间的问题记录下来,加上自己的理解希望能对其他朋友起到帮助。

正好那段时间也是传说中的金三银四,所以无形中也叫顺势而为吧😏。

Read more »

前言

之前在 Java-Interview 中提到过秒杀架构的设计,这次基于其中的理论简单实现了一下。

本次采用循序渐进的方式逐步提高性能达到并发秒杀的效果,文章较长请准备好瓜子板凳(liushuizhang😂)。

本文所有涉及的代码:

最终架构图:

系统架构设计.png

Read more »

前言

本文接着上文应用限流进行讨论。

之前谈到的限流方案只能针对于单个 JVM 有效,也就是单机应用。而对于现在普遍的分布式应用也得有一个分布式限流的方案。

基于此尝试写了这个组件:

https://github.com/crossoverJie/distributed-redis-tool

DEMO

以下采用的是

https://github.com/crossoverJie/springboot-cloud

来做演示。

在 Order 应用提供的接口中采取了限流。首先是配置了限流工具的 Bean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Configuration
public class RedisLimitConfig {


@Value("${redis.limit}")
private int limit;


@Autowired
private JedisConnectionFactory jedisConnectionFactory;

@Bean
public RedisLimit build() {
RedisClusterConnection clusterConnection = jedisConnectionFactory.getClusterConnection();
JedisCluster jedisCluster = (JedisCluster) clusterConnection.getNativeConnection();
RedisLimit redisLimit = new RedisLimit.Builder<>(jedisCluster)
.limit(limit)
.build();

return redisLimit;
}
}

接着在 Controller 使用组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Autowired
private RedisLimit redisLimit ;

@Override
@CheckReqNo
public BaseResponse<OrderNoResVO> getOrderNo(@RequestBody OrderNoReqVO orderNoReq) {
BaseResponse<OrderNoResVO> res = new BaseResponse();

//限流
boolean limit = redisLimit.limit();
if (!limit){
res.setCode(StatusEnum.REQUEST_LIMIT.getCode());
res.setMessage(StatusEnum.REQUEST_LIMIT.getMessage());
return res ;
}

res.setReqNo(orderNoReq.getReqNo());
if (null == orderNoReq.getAppId()){
throw new SBCException(StatusEnum.FAIL);
}
OrderNoResVO orderNoRes = new OrderNoResVO() ;
orderNoRes.setOrderId(DateUtil.getLongTime());
res.setCode(StatusEnum.SUCCESS.getCode());
res.setMessage(StatusEnum.SUCCESS.getMessage());
res.setDataBody(orderNoRes);
return res ;
}

为了方便使用,也提供了注解:

1
2
3
4
5
6
7
@Override
@ControllerLimit
public BaseResponse<OrderNoResVO> getOrderNoLimit(@RequestBody OrderNoReqVO orderNoReq) {
BaseResponse<OrderNoResVO> res = new BaseResponse();
// 业务逻辑
return res ;
}

该注解拦截了 http 请求,会再请求达到阈值时直接返回。

普通方法也可使用:

1
2
@CommonLimit
public void doSomething(){}

会在调用达到阈值时抛出异常。

为了模拟并发,在 User 应用中开启了 10 个线程调用 Order(限流次数为5) 接口(也可使用专业的并发测试工具 JMeter 等)。

Read more »

原文链接

Python?Java?Ruby?JavaScript?有非常多的选择。选择一种编程语言开始你的编码之旅不应该是一件艰巨的任务。

事实上:你将要学习的语言并不是特别重要,更重要的是学习编程的理念。对于任何编程语言来说知识的可传递性都是至关重要的。

我学习的第一门语言是 Java,学习了循环,while 循环,条件,函数,面向对象编程和许多编程理念。

然而,选择一门能在编程领域轻松找到工作的语言是更好的选择。对于初学者来说,我这里有一份列表推荐给你:

Read more »

前言

LRU 是 Least Recently Used 的简写,字面意思则是最近最少使用

通常用于缓存的淘汰策略实现,由于缓存的内存非常宝贵,所以需要根据某种规则来剔除数据保证内存不被撑满。

如常用的 Redis 就有以下几种策略:

策略 描述
volatile-lru 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
volatile-ttl 从已设置过期时间的数据集中挑选将要过期的数据淘汰
volatile-random 从已设置过期时间的数据集中任意选择数据淘汰
allkeys-lru 从所有数据集中挑选最近最少使用的数据淘汰
allkeys-random 从所有数据集中任意选择数据进行淘汰
no-envicition 禁止驱逐数据

摘抄自:https://github.com/CyC2018/Interview-Notebook/blob/master/notes/Redis.md#%E5%8D%81%E4%B8%89%E6%95%B0%E6%8D%AE%E6%B7%98%E6%B1%B0%E7%AD%96%E7%95%A5

Read more »

前言

分布式锁在分布式应用中应用广泛,想要搞懂一个新事物首先得了解它的由来,这样才能更加的理解甚至可以举一反三。

首先谈到分布式锁自然也就联想到分布式应用。

在我们将应用拆分为分布式应用之前的单机系统中,对一些并发场景读取公共资源时如扣库存,卖车票之类的需求可以简单的使用同步或者是加锁就可以实现。

但是应用分布式了之后系统由以前的单进程多线程的程序变为了多进程多线程,这时使用以上的解决方案明显就不够了。

因此业界常用的解决方案通常是借助于一个第三方组件并利用它自身的排他性来达到多进程的互斥。如:

  • 基于 DB 的唯一索引。
  • 基于 ZK 的临时有序节点。
  • 基于 Redis 的 NX EX 参数。

这里主要基于 Redis 进行讨论。

Read more »