A Bloom filter is a space-efficient probabilistic data structure, conceived by Burton Howard Bloom in 1970, that is used to test whether an element is a member of a set. False positive matches are possible, but false negatives are not, thus a Bloom filter has a 100% recall rate. In other words, a query returns either “possibly in set” or “definitely not in set”. —— From wikipedia.
Controller 层的职责
controller 层的主要职责:是对用户的输入进行校验、组织、重组、转换等,之后调用 service 层或者 repository 层对业务数据进行处理,同时对 service/repository 层的输出进行包装,不应该逾越其职责范围进行业务的处理或者数据层的读写
URL 规范
模式规范
强制:统一采用小写,并以中划线(-)作为分隔符,不得 进行驼峰式的大小写混合,不得 采用其它分割符。
参考文献:
- IETF 草案:https://www.ietf.org/rfc/rfc1738.txt
- 来自Google的建议:“we recommend that you use hyphens (-) instead of underscores (_) in your URLs”
- 参考文档:Dash- or underscore_ in URL Web address?
URL 的生成与拼接
建议: 采用
UriComponent
相关的组件,而非字符串拼接,可以避免较多的不规范及编码问题,如下所示:
1 | UriComponents uriComponents = UriComponentsBuilder.fromUriString("http://www.example.com/query") |
更多的实用方法请自行查阅API。
重试机制(RetryTemplate)
强制: 统一采用
Spring-Retry
库来完成重试操作,不得 通过循环等方式来自实现
方案有如下两种(推荐采用注解方式,特殊场景可以通过 RetryTemplate
自行定制):
注解式
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42@Slf4j
@EnableRetry
@Service
public class RetryCallService {
// 最大重试次数
private static final int MAX_ATTEMPTS = 10;
// 延迟策略
private static final long DELAY = 1000 * 2L;
private static final long MAX_DELAY = DELAY * 60;
private int count = 0;
private long start = 0;
@Retryable(value = {BizException.class},
maxAttempts = MAX_ATTEMPTS,
backoff = @Backoff(delay = DELAY, maxDelay = MAX_DELAY, multiplier = 2))
public Boolean retry() throws Exception {
if (start == 0) {
start = System.currentTimeMillis();
}
doSomething();
return true;
}
// 达到最大重试次数后的补偿方案
@Recover
public Boolean recover(BizException e) {
log.info("达到最大尝试次数,执行最后的补偿操作,异常信息为:{}", e.getMessage());
return false;
}
// 具体的业务逻辑
private void doSomething() throws Exception {
count++;
log.info("进行第 {} 次尝试,当前时间过去了:{} 秒", count, (System.currentTimeMillis() - start) / 1000);
throw new BizException("模拟业务异常");
}
}
JDK/bin下工具列表说明
appletviewer.exe
一种执行HTML文件上的Java小程序类的Java浏览器
apt.exe
注解处理工具(Annotation Processing Tool), SolarisTM 操作系统和 Linux上用于处理注释的工具
extcheck.exe
扩展检测工具,检测目标 jar 文件与当前安装方式扩展jar 文件间的版本冲突
MySQL分库分表的一些技巧
纵向分表
将本来可以在同一个表的内容,人为划分为多个表。(所谓的本来,是指按照关系型数据库的第三范式要求,是应该在同一个表的。)
分表理由:根据数据的活跃度进行分离,(因为不同活跃的数据,处理方式是不同的)
案例
对于一个博客系统,文章标题,作者,分类,创建时间等,是变化频率慢,查询次数多,而且最好有很好的实时性的数据,我们把它叫做冷数据。而博客的浏览量,回复数等,类似的统计信息,或者别的变化频率比较高的数据,我们把它叫做活跃数据。
所以,在进行数据库结构设计的时候,就应该考虑分表,首先是纵向分表的处理。
这样纵向分表后: 首先存储引擎的使用不同,冷数据使用MyIsam 可以有更好的查询数据。活跃数据,可以使用Innodb ,可以有更好的更新速度。
其次,对冷数据进行更多的从库配置,因为更多的操作时查询,这样来加快查询速度。对热数据,可以相对有更多的主库的横向分表处理。
其实,对于一些特殊的活跃数据,也可以考虑使用memcache ,redis之类的缓存,等累计到一定量再去更新数据库。或者mongodb 一类的nosql 数据库,这里只是举例,就先不说这个。
Introduction to Caffeine
1 Introduction
In this article, we’re going to take a look at Caffeine — a high-performance caching library for Java.
One fundamental difference between a cache and a Map is that a cache evicts stored items.
An eviction policy decides which objects should be deleted at any given time. This policy directly affects the cache’s hit rate — a crucial characteristic of caching libraries.
Caffeine uses the Window TinyLfu eviction policy, which provides a near-optimal hit rate.
Linux环境下安装Nginx
1. 概述
Nginx 是一个高性能的HTTP和反向代理服务器,官方地址为http://nginx.org/,这里不多做介绍。本次介绍使用源码编译安装,安装Nginx前需要安装C++编译环境,可使用以下命令安装:
Centos
1 | sudo yum install gcc gcc-c++ |
Ubuntu:
1 | apt-get install build-essential |
Nginx下载地址:http://nginx.org/en/download.html
MapStruct 介绍
1. 概述
在一个成熟的工程中,尤其是现在的分布式系统中,应用与应用之间,还有单独的应用细分模块之后,DO 一般不会让外部依赖,这时候需要在提供对外接口的模块里放 DTO 用于对象传输,也即是 DO 对象对内,DTO对象对外,DTO 可以根据业务需要变更,并不需要映射 DO 的全部属性。
这种 对象与对象之间的互相转换,就需要有一个专门用来解决转换问题的工具,毕竟每一个字段都 get/set 会很麻烦。
MapStruct 就是这样的一个属性映射工具,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。MapStruct官网地址: mapstruct.org。