缓存那些事
作者: 明辉链接:https://tech.meituan.com/2017/03/17/cache-about.html来源:美团技术团队著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
前言一般而言,现在互联网应用(网站或App)的整体流程,可以概括如图1所示,用户请求从界面(浏览器或App界面)到网络转发、应用服务再到存储(数据库或文件系统),然后返回到界面呈现内容。
随着互联网的普及,内容信息越来越复杂,用户数和访问量越来越大,我们的应用需要支撑更多的并发量,同时我们的应用服务器和数据库服务器所做的计算也越来越多。但是往往我们的应用服务器资源是有限的,且技术变革是缓慢的,数据库每秒能接受的请求次数也是有限的(或者文件的读写也是有限的),如何能够有效利用有限的资源来提供尽可能大的吞吐量?一个有效的办法就是引入缓存,打破标准流程,每个环节中请求可以从缓存中直接获取目标数据并返回,从而减少计算量,有效提升响应速度,让有限的资源服务更多的用户。
如图1所示,缓存的使用可以出现在1~4的各个环节中,每个环节的缓存方案与使用各有特点。
图1 互联网应用一般流程
缓 ...
聊聊MyBatis缓存机制
作者: 凯伦链接:https://tech.meituan.com/2018/01/19/mybatis-cache.html来源:美团技术团队著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
前言MyBatis是常见的Java数据库访问层框架。在日常工作中,开发人员多数情况下是使用MyBatis的默认缓存配置,但是MyBatis缓存机制有一些不足之处,在使用中容易引起脏数据,形成一些潜在的隐患。个人在业务开发中也处理过一些由于MyBatis缓存引发的开发问题,带着个人的兴趣,希望从应用及源码的角度为读者梳理MyBatis缓存机制。
本次分析中涉及到的代码和数据库表均放在GitHub上,地址: mybatis-cache-demo 。
目录本文按照以下顺序展开。
一级缓存介绍及相关配置。
一级缓存工作流程及源码分析。
一级缓存总结。
二级缓存介绍及相关配置。
二级缓存源码分析。
二级缓存总结。
全文总结。
一级缓存一级缓存介绍在应用运行过程中,我们有可能在一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis提供了一级缓存的方案优化这部分场景,如 ...
Java实现数字千位分隔符
DecimalFormat1new DecimalFormat(",###").format(new BigDecimal(1234567890).longValue())
String.format1String.format("%,d",new BigDecimal(1234567890).longValue())
正则表达式1String.valueOf(new BigDecimal(1234567890).longValue()).replaceAll("(\\d)(?=(\\d{3})+\$)", "\$1,")
1234567891011121314151617#!/usr/bin/perluse strict;use warnings;my $num = 1234556789;#纯数据模式$num =~ s/(?<=\d)(?=(\d{3})+$)/,/g;print $num,"\n";#带有小数点模式$num = 12 ...
Java符号运算
先给大家晒一晒代码
12345678910import cn.hutool.core.util.HexUtil;String hex = "1f8698690e02ca16618550ef7f19da8e945b555a";byte[] hexByte = HexUtil.decodeHex(hex);int bin_code = (hexByte[10] & 0x7f) << 24 | (hexByte[11] & 0xff) << 16 | (hexByte[12] & 0xff) << 8 | (hexByte[13] & 0xff);bin_code = bin_code % (int)Math.pow(10,6);
看到这段代码,大家什么感受。
尤其平时大家在翻阅源码时,这样的代码更是屡见不鲜。
是不是脑袋已经泛起了涟漪。小小的脑袋里面,充满了大大的问号?
这是个什么东东,是什么运算,运算过程是什么,运算结果又是什么样的。
今天我们就来好好探究探究里面的秘密。
其实这些运算都 ...
Java线程池实现原理及其在美团业务中的实践
作者: 陆晨链接:https://tech.meituan.com/2020/04/02/java-pooling-pratice-in-meituan.html来源:美团技术团队著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C提供的线程池:ThreadPoolExecutor类,帮助开发人员管理线程并方便地执行并行任务。了解并合理使用线程池,是一个开发人员必修的基本功。
本文开篇简述线程池概念和用途,接着结合线程池的源码,帮助读者领略线程池的设计思路,最后回归实践,通过案例讲述使用线程池遇到的问题,并给出了一种动态化线程池解决方案。
一、写在前面1.1 线程池是什么线程池(Thread Pool)是一种基于池化思想管理线程的工具,经常出现在多线程服务器中,如MySQL。
线程过多会带来额外的开销,其中包括创建销毁线程的开销、调度线程的开销等等,同时也降低了计算机的整体性能。线程池维护多个线程,等待监督管理者分配可并发执行的任务 ...
是时候聊聊Google Authenticator了
我们平常在进行账号安全设置的时候,平台都会建议设置二次验证。
然后会生成一个二维码,手机下载Google Authenticator,去扫描这个二维码,扫描完成后就会出现一组6位数字。
我们后续每次进行重要操作的时候,都会输入这组6位数字来进行安全验证。
关键这组数字还是动态的,每隔十几秒就会刷新一次,而且还可以断网使用。
当时就好了奇了,这么神奇吗,动态刷新还可以断网,他咋和服务器交互验证的呢。
先来用一用探索真理最好的途径就是实践,想要搞懂它,我们不妨来使用使用。
首先,我们得先整一个二维码,这个二维码用来绑定Google Authenticator。
我们去PSN的官网来弄一个,下面我已经弄好了,大家自行扫描。二维码别外传呦。骗你的,二维码是我自己生成的
然后,掏出我们的 iPhone 100 Pro Max 来扫描一下。
扫描完了。
然后就得到了神奇的6位数 213 993,这就是我们以后进行安全认证的法宝了。
除了6位数字,我们还看到了其他的一些信息,我们来一一说明一下
Sony 一般都是平台信息
longl ...
Java魔法类:Unsafe应用解析
作者:璐璐链接:https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html来源:美团技术团队著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
前言Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重。
注:本文对sun.misc.Unsafe公共API功能及相关应用场景进行介绍。
基本介绍如下Unsafe源码所示,Unsafe类为一单例实现,提供静态方法getUnsafe获取Unsafe实例,当且仅当调用getUnsafe方法的类为引导类加载器所 ...
红包算法
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189import java.math.BigDecimal;import java.m ...
消息队列
1. 消息队列的基本作用消息队列的主要作用是:解耦、异步、削峰。
解耦A 系统通过接口调用发送数据到 B、C、D 三个系统。那如果现在 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?现在 A 系统又要发送第二种数据了呢?这样的话 A 系统的维护成本就非常的高,而且 A 系统要时时刻刻考虑 B、C、D、E 四个系统如果出现故障该怎么办?A 系统是重发还是先把消息保存起来呢?使用消息队列就可以解决这个问题。A 系统只负责生产数据,不需要考虑消息被哪个系统来消费。
异步A 系统需要发送个请求给 B 系统处理,由于 B 系统需要查询数据库花费时间较长,以至于 A 系统要等待 B 系统处理完毕后再发送下个请求,造成 A 系统资源浪费。使用消息队列后,A 系统生产完消息后直接丢进消息队列,不用等待 B 系统的结果,直接继续去干自己的事情了。
削峰A 系统调用 B 系统处理数据,每天 0 点到 12 点,A 系统风平浪静,每秒并发请求数量就 100 个。结果每次一到 12 点 ~ 13 点,每秒并发请求数量突然会暴增到 1 万条。但是 B 系统最大的处理能力就只能是每秒钟处理 1000 个 ...
雪花算法
是什么SnowFlake 中文意思为雪花,故称为雪花算法。最早是 Twitter 公司在其内部用于分布式环境下生成唯一 ID。在 2014 年开源 scala 语言版本。
ID 结构
雪花算法原理就是生成一个的 64 位比特位的 long 类型的唯一 id。
第 1 位。二进制中数字表达形式最高位为 1 的代表负数,为 0 代表正数。我们生成的 id 一般都使用整数,所以这个最高位固定是0
接下来 41 位存储毫秒级时间戳,2^41/(1000_60_60_24_365)=69,大概可以使用 69 年。
再接下 10 位存储机器码,包括 5 位 datacenterId 和 5 位 workerId。最多可以部署 2^10=1024 台机器。
最后 12 位存储序列号。同一毫秒时间戳时,通过这个递增的序列号来区分。即对于同一台机器而言,同一毫秒时间戳下,可以生成 2^12=4096 个不重复 id。
算法实现(Java)12345678910111213141516171819202122232425262728293031323334353 ...