MQ使用总结(一)如何保证消息按顺序执行
为什么要保证顺序消息队列中的若干消息如果是对同一个数据进行操作,这些操作具有前后的关系,必须要按前后的顺序执行,否则就会造成数据异常。举例:比如通过mysql binlog进行两个数据库的数据同步,由于对数据库的数据操作是具有顺序性的,如果操作顺序搞反,就会造成不可估量的错误。比如数据库对一条数据依次进行了 插入->更新->删除操作,这个顺序必须是这样,如果在同步过程中,消息的顺序变成了 删除->插入->更新,那么原本应该被删除的数据,就没有被删除,造成数据的不一致问题。
出现顺序错乱的场景rabbitmq
一个queue,有多个consumer去消费,这样就会造成顺序的错误,consumer从MQ里面读取数据是有序的,但是每个consumer的执行时间是不固定的,无法保证先读到消息的consumer一定先完成操作,这样就会出现消息并没有按照顺序执行,造成数据顺序错误。
一个queue对应一个consumer,但是consumer里面进行了多线程消费,这样也会造成消息消费顺序错误。
kafka
kafka一个topic,一个partition,一个 ...
深入学习jvm与垃圾回收
一、 Java内存区域常见面试题
介绍下 Java 内存区域(运行时数据区)
Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么)
对象的访问定位的两种方式(句柄和直接指针两种方式)
String 类和常量池
8 种基本类型的包装类和常量池
1. 运行时数据区域 Java 虚拟机在执行 Java 程序的过程中会把它管理的内存划分成若干个不同的数据区域。JDK. 1.8 和之前的版本略有不同。
JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区域【JAVA 堆、方法区】、直接内存。线程私有数据区域生命周期与线程相同, 依赖用户线程的 启动/结束 而 创建/销毁 (在 Hotspot VM 内, 每个线程都与操作系统的本地线程直接映射, 因此这部分内存区域的存/否跟随本地线程的生/死对应)。
1.1程序计数器(线程私有)一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的程序计数器,这类内存也称为“线程私有”的内存。正在执行 java 方法的话, ...
mvcc浅析
在讲Mvcc前,我觉得有必要先了解一下InnoDB的行锁。mysql从5.5.5开始使用InnoDB作为默认存储引擎,lock的对象是事务,用来锁定的是数据库中的对象,如表、页、行。并且一般lock的对象仅在事务commit或rollback后进行释放(不同事务隔离级别释放的时间可能不同)。InnoDB存储引擎实现了如下两种标准的行锁:
共享锁(S Lock)允许事务读一行数据
排他锁(X Lock)允许事务删除或更新一行数据
说明:
读锁、S锁,若事务T对数据对象A加上S锁,则事务T可以读A但不能修改A,其他只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这保证了其他事务可以读A,但在T释放A上S锁之前不能对A做任何修改。
写锁、X锁,若事务T对数据对象A加上X锁,事务T可以读A也可以修改A,其他事务不能再对A加任何锁,直到T释放A上的锁,这保证了其他事务在T释放A上的锁之前不能再读取和修改A。
一致性非锁定读一致性的非锁定读(consistent nonlocking read )是指InnoDB通过行多版本控制(multi versioning)的方式来读取当前 ...
布隆过滤器原理及使用
什么是布隆过滤器?我们来看这么一个场景:目标网站有上千万个URL,如何判断某个URL是否已经访问过?使用DB存储的话,就是把每个URL存入DB,然后每次访问URL前执行
1slect id from table where url = 'xxxx'
但随着URL数据量增多,每次请求前都要访问DB一次,效率非常低。当然,也可以用redis的set结构存储URL,优于DB存储,但也同样存在一个问题:耗费内存过多。如何解决?布隆过滤器!
布隆过滤器从本质上讲是一个位数组,位数组就是数组的每个元素都只占用1bit。每个元素只能是0或者1。这样申请一个10000个元素的位数组只占用 10000/8 = 1250B 的空间。布隆过滤器除了一个位数组,还有K个哈希函数。当一个元素加入布隆过滤器的时候,会进行如下操作:
使用K个哈希函数对元素值进行K次计算,得到K个哈希值。
根据得到的哈希值,在数组中把对应下标的值设置为1。
如上图:url1通过f1,f2,f3 三个哈希函数计算得到3个值,把数组中的三个位置设置为1。
要判断一个值是否存在,则只需对元素值 ...
生产环境缓存失效解决方案
Redis的持久化机制Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。
持久化方式
RDB 持久化 RDB 持久化方式能够在指定的时间间隔对你的数据进行快照存储
AOF(append only file)持久化 AOF 持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据
RDB 方式
客户端直接通过命令BGSAVE或者SAVE来创建一个内存快照
BGSAVE 调用fork来创建一个子进程,子进程负责将快照写入磁盘,而父进程仍然继续处理命令。
SAVE 执行SAVE命令过程中,不再响应其他命令。
在redis.conf中调整save配置选项,当在规定的时间内,Redis发生了写操作的个数满足条件会触发发生
BGSAVE命令
123456# 900秒之内至少一次写操作save 900 1 # 300秒之内至少发生10次写操作save 300 10# 60秒之内发生至少10000次save 60 10000 ...
高可用Nginx集群安装搭建手册
LVS搭建Nginx集群准备工作环境说明共需要三台linux centos服务器,一台LVS,两台RealServer,端口号必须保持一致,设为80,所以需要3台服务器。
设定IP环境如下
服务名
IP
端口
作用
LVS-Director
VIP 192.168.120.200 RIP 192.168.120.58
80
运行LVS均衡调度,对外提供虚拟IP访问
RealServer-Nginx1
192.168.120.83
80
运行nginx及tomcat服务,作为真实服务 1
RealServer-Nginx2
192.168.120.58
80
运行nginx及tomcat服务,作为真实服务 2
LVS-Director负责将80端口的请求,负载均衡到Nginx1、Nginx2两台真实服务器上去,接下来我们将进行配置LVS-Director的路由方式-DR,直接路由。准备IP地址信息打印程序balancer-1.0.0.jar,http://hostname:port/server/ip,打印服务器的IP端口号信息。
启动RealServer服务 ...
ElasticSearch Centos7 安装
准备工作开放端口关闭防火墙
12systemctl stop firewalldsystemctl disable firewalld
或者开放对应的端口号,比如ElasticSearch的9300、9200,Kibana的5601
1234sudo firewall-cmd --zone=public --add-port=9300/tcp --permanentsudo firewall-cmd --zone=public --add-port=9200/tcp --permanentsudo firewall-cmd --zone=public --add-port=5601/tcp --permanentsudo firewall-cmd --reload
新建用户1234# 添加用户备用useradd elastic# 设置密码passwd elastic
创建安装目录1mkdir /usr/local/elastic
下载安装包下载安装包 elasticsearch、kibana、IK Analysis,这里下载的是7.5.1版本,大家选择自己需要的版本 ...
Redis安装及集群搭建手册
1、 环境信息12centos7redis5
单机安装
123456789101112wget http://download.redis.io/releases/redis-5.0.3.tar.gztar xzf redis-5.0.3.tar.gz -C /usr/local/cd /usr/local/redis-5.0.3make# 启动Redissrc/redis-server# 使用客户端命令窗口src/redis-cliredis> set foo barOKredis> get foo"bar"
2、整体集群信息1234# 以直接在一台机器上实现上述的伪集群,因为端口号特意设置为不同的。# 重点:不论机器多少,对于部署过程都是一样的,只不过是在不同机器启动redis-server而已192.168.100.242 (6381- 6386共6个端口)# 注意事项:如果你的服务器有多个IP,那你操作下面步骤时,尽量使用你的客户端能够访问的IP
3、安装Redis每台服务器上面都要下载安装
123456789wget http://d ...
Mysql Explain工具使用及索引调优
使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返 回执行计划的信息,而不是执行这条SQL
注意:如果 from 中包含子查询,仍会执行该子查询,将结果放入临时表中
explain分析示例示例表:
12345678910111213141516171819202122232425262728CREATE TABLE `actor` ( `id` int(11) NOT NULL, `name` varchar(45) DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `actor`(`id`,`name`,`update_time`)VALUES(1,'a','2017‐12‐22 15:27:18'), (2, ...
Java 线程池原理分析
简介线程池可以简单看做是一组线程的集合,通过使用线程池,我们可以方便的复用线程,避免了频繁创建和销毁线程所带来的开销。在应用上,线程池可应用在后端相关服务中。比如 Web 服务器,数据库服务器等。以 Web 服务器为例,假如 Web 服务器会收到大量短时的 HTTP 请求,如果此时我们简单的为每个 HTTP 请求创建一个处理线程,那么服务器的资源将会很快被耗尽。当然我们也可以自己去管理并复用已创建的线程,以限制资源的消耗量,但这样会使用程序的逻辑变复杂。好在,幸运的是,我们不必那样做。在 JDK 1.5 中,官方已经提供了强大的线程池工具类。通过使用这些工具类,我们可以用低廉的代价使用多线程技术。
线程池作为 Java 并发重要的工具类,在会用的基础上,我觉得很有必要去学习一下线程池的相关原理。毕竟线程池除了要管理线程,还要管理任务,同时还要具备统计功能。所以多了解一点,还是可以扩充眼界的,同时也可以更为熟悉线程池技术。
继承体系线程池所涉及到的接口和类并不是很多,其继承体系也相对简单。相关继承关系如下:
如上图,最顶层的接口 Executor 仅声明了一个方法execute。Exe ...