前言
架构
- 首先我讲一下整体的架构(假装很厉害吧);
- JedisAdapter用来做Redis的适配,我们对一些redis命令进行封装;
- RedisKeyUtil 是用来记录redis中的key的;比如我们通过一个实体类别+实体id为key,然后就可以找到这个实体的关注者;相同的,我们可以通过userId+ 实体类别,就可以找到用户在这个方向关注什么了;
- 然后我们想一下,一个关注事件发生后,会怎么样呢,是不是会发生私信事件,所以我们就可以在消息处理部分加一个handler,然后关注时,发出这样的消息;
- 然后我们想一下,加上关注后,首先是我们关注了谁,关注了那些问题,事件,什么之类的,这些就可以通过userId+实体类别取出;然后是关注者,不管是问题还是人,都可以通过实体类别+实体id 找到它的关注者;还有就是当我们关注或者取消关注时,页面会发生变化,所以关注的代码是最多的,因为牵涉面最多,前端页面最多;
- 所以其实整个关注中最重要的就是service先上层提供的增删改查服务;然后就是controller修改viewObject; 其他的其实只是代码量的问题罢了
more >>
起因
- 消息队列顾名思义是发消息的,但是它并不是一个用来发消息功能;它的作用是用于线程与线程间,进程与进程间的通信;
消息队列
- 消息队列可认为是一种通用的解决方案,一种进程(线程)间通信的方案;有句话是这样讲的,不要以共享内存来实现通信,而应该通过通信来实现共享内存;当我们想把一件事情共享给多个进程,而又不需要强烈的时间限制,那么通信是一种很好的解决方案;两个进程如果都需要某个变量,那就通过通信传递,实现共享,协同工作;而消息队列是什么样的消息呢?它的通信实际上传递的是事件,或者工作;
- 消息队列的目的是为了将一些不那么需要及时响应的活传递给另一个线程或者进程;这样主线程或者进程就可以快速的处理事情;
- 举个不太恰当的例子,我是某办事处的老大,每天有n多投诉会到我们办事处,我会差不多看一遍,分分类,然后如果有红色等级就自己批注一下,否则的话,我就通通交给门口看门的街道办事处大爷;然后大爷就会找邻里街坊的把事情给处理掉;
- 特点是:
- 我很忙,主线程的运行不能搁置,就好像双11,大家总不能都挤在入口的服务器上,我其实做了负载均衡或者代理的作用,所有事情都往我这里投诉,然后我在分配下去;
- 异步性,这个处理并不是必须及时的,要是我的顶头上司过来投诉,我才不管别人,专门服务与我的上司;
- 投诉很多,假设每天就一个投诉,那占用我的全部时间也没关系,但是当投诉堆积成山,我就会陷入宕机的状态,无法处理;
- 一个消费者也可以是一个生产者,比如说快递吧,一件商品运到目的地需要很多手传递,我们完全可以认为这是一个流水线的过程,任何一个消费者都可能是下一步的生产者;
more >>
起因
实现原理
- 首先我们知道volatile能保证原子性,但是又不能保证同步,很奇怪吧;但是我写过一个例子,i++;非volatile会存在后面的值比前面小的情况,volatile不存在,只会存在相同的情形;这是为什么呢?
- 首先我们假定就是多个cpu,每cpu一个线程,我们知道内存里面放了成堆的数据,cpu每次取要用的放在寄存器里,那么多个线程一起处理一个变量,每个cpu的值很可能就是不一样的;
- 然后我们的想法是,大家必须都应该是最新的数据,这就要求cpu运行时,做了什么操作,寄存器需要立马回写到内存,然后它会将所有其他cpu所持有的值更新;
- 通过这两个步骤我们就实现了读/写原子性,我们读的时候,这个值一定是最新的,但是加入我们10个线程同时读到最新的值为1,然后同时++;然后再各自写回内存,那么就会出现不同步的情况;但是不会出现后面的值比前面的值小的情况;
- i++本来是想cpu1 i++一下,cpu2 i++一下。。。 所有cpu分开进行加锁操作;
- 如果不用volatile关键词,会出现i++反而变小,因为各个cpu持有的i不一样,比如大家先在cpu1 和 cpu2 读入 i = 1,然后cpu1 i++; 写回 i = 2;cpu3读取i = 2; 执行i++; 写回i =3 ;然后cpu2 执行 i++; 写回 i = 2; 这样就出现后面比前面小的状态
- 使用volatile,在cpu1 写回 i =2 时,会通知所有cpu i = 2;但是存在问题时,加入通知的时候cpu2 已经做完 i++; 然后 通知 i = 2;那么cpu2 也会写回 i = 2 ;也就是相同的值;
more >>
前言
REDIS
- 总是听nosql,但还真不懂啊原来nosql真的和传统数据库不一样;是依赖与传统中的集合来的
- redis的应用与集合的特性
- hash:在一个hash表里面,键是string,值又是一个hash,然后就可以加很多很多东西;因为hash表本身就可以扩容的嘛;好处就是可以随着对象随便的增多属性或者减少属性;
- set 和普通的set一样,用于去重,求交集啥的,都是很厉害的;比如我们的点赞功能,把一群人放在一个集合里,算一下有多少,就得到赞数
- sortedset 排序的set,相当于优先队列,搞个什么排行榜的不错
- list 一个普通的双向队列,最普通的列表呗
- kv ,过期时间啥的
more >>
前言
- 计算机网络不管怎样,都是一个好难的学科啊;各种纷繁复杂的协议,要考虑的问题也实在是太多了;
概述
- 运输层提供逻辑通信,服务主体是应用层的各种应用程序,让我们感觉我们所享用的服务就是自己电脑上的,而实际上却是超级远的地方;
- 由于运输层是服务于各种应用程序的,所以分解与合并就是必然的;注意分解并不是分解成报文段,报文分解为小的报文段,主要原因是因为网络需求;报文段中的端口号才促使了分解与合并,运输层来来往往一大堆的报文段,将它们准确的发往某个主机的套接字,后者接受到某个套接字上,这才是多路分解的本质;
- 两家人寄信为例,年龄大的姐姐把信都收到然后分发给其他人,或者收集信,一起发出去
- udp套接字是由一个二元组标识的,目的ip和目地端口号;也就是说不管从哪里来的报文段,只要ip+端口一样,处理它们的套接字就一定相同;但是这不代表报文段中就没有端口和ip
- tcp套接字有四元组标识,以http为例,要不然大家访问百度,就一个ip+端口,就映射一个套接字,那不累死了;
more >>