技术进阶之路
- java
- mysql()
- redis
- mybatis
- RPC(hessian,grpc,thrift,protobuf)
- Spring FrameWork(Spring MVC,Spring Boot)
- Rabbitmq
- Mongodb(mongoose)
- Nodejs(express,promise,callback)
并发多线程,网络IO
- 并发编程
场景1:
将用户交易记录转化成用户积分,计算时需要防止并发出现积分计算错误现象
场景2:
在推送APP消息推送过程中,总是出现一条消息推送两次给用户的现象。
JVM内存模型,多线程之间共享变量造成
场景3:
日志打印,同一请求在多台服务器上打印日志(同一行日志)
场景4:
项目中使用Spring AOP事务不合理,redis缓存也被事务包裹,登录时造成死锁
场景5: 100ms内响应用户请求,最高峰时候单位时间高几百万的用户请求,高并发,服务不宕机(高可用),设计方案- (应用)服务分布式部署,防止一台服务器宕机之后影响其他服务。
- 数据库设计读写分离(分表分库),一主多重,主从同步
- 缓存的设计,可使用分布式集群部署缓存,防止数据库雪崩
- 接口代码中使用hystrix服务降级和过载保护
项目中使用Spring AOP事务不合理,redis缓存也被事务包裹,登录时造成死锁
线程安全
synchronized
volatile
CountDownLatch 能够统计线程正在执行个数,并且将所有计算结果返回IO
- 同步与异步
同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)所谓同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回。但是一旦调用返回,就得到返回值了。 - 阻塞与非阻塞
阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态. - HTTP Response Entity多次读取,会抛出视图读取已经关闭的流异常
4.
- 同步与异步
缓存数据库读写
缓存Redis
- redis中key的前缀生成策略如下:
- 基础方法:
以项目+模块的方式进行分开。项目采用项目名称缩写,模块采用模块的缩写。举例:sdk行为的 SDK为项目缩写,ACTION为模块缩写,中间采用下划线 “_” 分割。则前缀key为 “SDK _ACTION” 。 - 高级方法:
对项目进行编码,采用16进展数。比如使用三位,对模块进行编码,比如使用三位。举例:sdk行为的,SDK编码:000,行为模块编码000,则前缀key为000000
以基础方法命名key000000
该编码,短小,唯一。能减少内存。只要维护好字典表,就能够快速的查询到对应的项目。为最优的解决办法。(仅供参考)
- 基础方法:
- 缓存淘汰策略:
- Redis发布订阅模式(pub/sub):
- Redis实现Session
- session其实是在cookie中保存了一个sessionid,用户每次访问都将sessionid发给服务器,服务器通过ID查找用户对应的状态数据。
- 在这里,Redis处理方式也是在cookie中定义一个sessionid,程序需要取得用户状态时将sessionid做为key在Redis中查找。
- 同时session支持用户在一定时间不访问将session回收。借用Redis中Keys支持过期时间的特性支持这个功能
我们使用redis缓存用户登录信息,没有使用seesion。将用户的用户名加盐加密作为key在redis中缓存起来,并设置过期时间,同时将这个key作为sessionId写回cookies中
- Redis实现分布式锁setnx,hsetnx
- Redis事务
WATCH
、MULTI/EXEC
、UNWATCH/DISCARD
,特别需要注意,分布式中不支持事务。Redis的WATCH是一种乐观锁模型。 Redis pipeline
Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。
- redis中key的前缀生成策略如下:
数据库Mysql
- 数据库读写分离
Spring AOP
作为切入点控制读库写库
使用org.apache.commons.dbcp.BasicDataSource
数据库连接池 - issue -> “The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server”
由于数据库回收了连接,而系统的缓冲池不知道,继续使用被回收的连接所致的。
- 数据库读写分离
系统架构
分布式数据库,主从读写分离,多台redis,应用分布式部署,自动化构建,自动化检测脚本,日志搜集系统,hessian rpc,nodejs,python
- 微服务架构
spring boot, spring cloud 分布式
nginx分布式部署方案,nginx负载均衡算法round-robin
,轮询(默认)weight
轮询权值,指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。ip_hash
,每个请求按访问IP的哈希结果分配,使来自同一个IP的访客固定访问一台后端服务器,并且可以有效解决动态网页存在的session共享问题。
4、fair
,比weight
,ip_hash
更加智能的负载均衡算法,fair算法可以根据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间 来分配请求,响应时间短的优先分配。Nginx本身不支持fair,如果需要这种调度算法,则必须安装upstream_fair模块。
5、url_hash
,按访问的URL的哈希结果来分配请求,使每个URL定向到一台后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身不支持url_hash,如果需要这种调度算法,则必须安装Nginx的hash软件包。
用户体系
- 常量结构