- 博客(72)
- 资源 (8)
- 问答 (3)
- 收藏
- 关注
![](https://csdnimg.cn/release/blogv2/dist/pc/img/listFixedTop.png)
原创 如何构建营销活动平台(一):前言概述
背景笔者接触营销活动已经接近半年时间,围绕C端用户的邀新,留存,促活也上线了一些营销活动,为了实现组件化,在编程过程中也一直在思考如何搭建一个营销平台,从而实现运营活动的配置化和扩展性,忙中偷闲,对半年来的营销活动工作做了一些总结和梳理,以及营销活动平台整体的业务规划,以下是这半年来的思考和沉淀。git源码地址:git clone https://github.com/caisl/acti...
2019-02-22 20:28:46
5518
1
![](https://csdnimg.cn/release/blogv2/dist/pc/img/listFixedTop.png)
原创 如何构建营销活动平台(二):业务功能设计
营销活动主流程功能描述营销活动平台模块划分通过上图,我们可以了解各个产品模块在营销平台中的定位,一个规范的完整的营销体系架构营销业务规划重要性一个完整的营销体系规划对于后续营销活动的策划,设计,管理,开发提供了很多帮助。从活动的实现角度来看,很难做到一套营销系统支持所有类型的活动,但是我们可以分析多个活动的共性,从而抽象出来一些相同的功能模块,制定一套活动设计的规范,系统编码层...
2019-01-29 15:55:16
7325
原创 记一次大事务导致的数据库死锁引起线上服务器load飙升的故障
一、背景描述公司业务系统由多个语言开发,核心业务由.net团队支持,数据存储在sqlServer中,为了使用这些数据由JAVA团队在上层做一个数据聚合平台,创建了个职责单一的新应用来做数据转换,同步到底层mysql数据库中,对外提供了一个标准接口由业务方通过定时任务分批同步,支持一次传输多条数据,数据同步策略是每秒6个线程并发同步5条记录,同步失败会在1,2,4s内重试三次二、故障现场第一次故障现象: api层服务异常日志告警,同步数据服务dubbo服务超时5s,但是业务应用中没有任何异常日志,跟业
2020-12-29 14:58:52
1872
原创 记一次后台订单列表检索慢SQL优化实践
记一次后台订单列表检索慢SQL优化实践一、背景介绍二、设计思路如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入一、背景介绍先简单介绍下我们的故事背景~需求描述:新增一种订单类型order_flag,然后在后台可以根据条件分页检索订单表数据量:165w,单库单表表
2020-07-29 16:25:38
893
原创 JVM(二) :垃圾回收机制
一、怎么判断是垃圾引用计数可达性分析二、如何回收1. 分带收集算法1.1 标记-清除(老年代)该算法会有两个问题:1. 效率问题,标记和清除效率不高。2. 空间问题: 标记清除后会产生大量不连续的内存碎片, 空间碎片太多可能会导致在运行过程中需要分配较大对象时无法找到足够的连续内存而不得不提前触发另一次垃圾收集。所以它一般用于"垃圾不太多的区域,比如老年代"。1.2 复制(...
2019-08-03 14:40:23
336
原创 HashedWheelTimer原理介绍
一、前言之前一直研究延迟队列的时间方式,调研过挺多技术,Netty中提供的HashedWheelTimer时间轮算法的实现也是其中一种。于是就研究了下内部实现的原理,研究的代码的版本如下:<groupId>io.netty</groupId><artifactId>netty-parent</artifactId><version&g...
2019-06-29 18:22:10
7648
1
原创 JVM(一) :Java内存区域和HotSpot介绍
一、运行时内存划分在JDK1.7中,根据Java虚拟机的规范,将其所管理的内存划分为以下这个运行时数据区域:1. 程序计数器当前线程所执行的字节码的行号指示器。每个线程都独立拥有一个程序计数器。如果线程正在执行的是一个Java方法,则计数器保存正在执行的字节码指令地址,如果是Native方法则程序计数器的值则为空(Undefined)。程序计数器是Java虚拟机规范中唯一没有规定任何O...
2019-06-29 18:12:25
828
原创 如何构建延迟任务调度系统(三):架构设计
功能设计系统功能:延迟任务调度系统提供统一的任务操作接口给业务方调用,业务方可以提交任务,取消任务,查询任务状态。调度服务属于底层应用,因此采用MQ的方式解耦,所有触发的延迟任务都通过消息的方式发送给业务消费方,由消费方控制流量,业务幂等。同时也保证了任务的重试机制。采用技术:elastic-job + db + delayQueue + mq整体架构业务调用方业务方在需要延迟...
2019-05-31 20:35:40
910
原创 阿里云CentOS搭建zookeeper集群环境
1.下载zk安装包cd /home/user/zkwget https://archive.apache.org/dist/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz2.zk包解压tar -zxvf zookeeper-3.4.12.tar.gz3.搭建3个节点的zk伪分布式集群在同一台服务器上,部署一个3个ZooKeepe...
2019-04-28 10:54:23
752
原创 如何构建延迟任务调度系统(二):技术调研
延时队列实现的几种方式java.util.Timer + java.util.TimerTaskjava.util.concurrent.ScheduledExecutorServiceQuartzjava.util.concurrent.DelayQueue数据库轮询redis过期键通知rocketMQ中的延时队列1. Timer+TimerTask使用 Timer 实现任...
2019-03-29 16:04:47
327
原创 如何构建延迟任务调度系统(一):需求目标
1.需求描述之前笔者接触过一些营销业务场景,比如说:用户注册未登录过APP第二天早上10点发一条营销短信促活红包过期前两天短信通知,下午16:00发送等等定时任务处理业务。采用的技术方案是定时任务扫数据汇总表,分页读取一定数量然后处理然而随着业务的发展,业务多元化,遇到了以下场景:拼团砍价活动过期前半小时提醒订单提交半小时内没有完成支付,订单自动取消,库存退还用户几天内没有...
2019-03-29 16:03:54
561
1
原创 如何构建营销活动平台(五):单元测试
接入指南同步仓库到本地git clone https://github.com/caisl/activity-platform.git根据实际业务调整代码DB设计activity-platform对营销活动流程框架和规则引擎提供了详细的设计和分析,DB请根据实际的需求设计,这里就不提供详细的内容。新活动接入举例:接入新人有礼活动,实现FunctionCodeEnu...
2019-02-22 20:23:27
1333
1
原创 如何构建营销活动平台(四):规则引擎设计
前言前面将活动抽象成了规则检验和一系列的操作,不同的活动的规则有重叠也有不同,如何设计才能保证最好的扩展性。规则引擎的出现就是制定一套规则检验的模型,下面来看下具体的设计。核心UML图组件介绍主要分为以下三个关键模块规则实体存储规则属性规则检验器执行规则检验,检验不通过可以自定义文案,该文案可以展示给用户看执行引擎串联业务请求和规则检验使用场景活动参与条件判断...
2019-02-21 10:02:00
12141
7
原创 如何构建营销活动平台(三):活动平台扩展性演进
前言经过了几个月的努力,初步建立了营销平台,也承载了几个营销活动。但是也存在规划工作不充分,代码层面要求未规范,导致后续的营销活动策划,设计,管理,开发出现了一系列的问题,包括不能快速迭代接入新的营销活动,不能及时响应运营和市场的节奏一期应用搭建完成接入第一个活动之后,对于规范这块要求松懈,同时由于多个项目时间排期周期赶,多人撸代码风格不一致,导致了一系列的技术债。所谓就是先污染后治理,...
2019-02-14 18:18:39
5791
8
原创 索引(三)查询性能优化
索引(三)查询性能优化高性能MYSQL需要设计最优的库表结构,建立最好的索引,合理的设计查询。查询优化,索引优化,库表结构优化三辆大车需要起头并进,才能达到最好的性能。查询的生命周期MySQL查询的生命周期:客户端发送一条查询给服务器服务器先检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果,否则进入下一阶段。服务器进行SQL解析,预处理,再由优化器生成对应...
2019-01-23 14:55:13
340
原创 索引(二)innodb索引
索引(二)innodb索引B+树索引innoDB中的B+树索引可以分为两种索引:聚集索引辅助索引聚集索引和辅助索引的不同点在于叶子节点存放的是否是一整行信息这两个名字虽然都叫做索引,但是这并不是一种单独的索引类型,而是一种数据存储方式。聚集索引聚集索引就是按照每张表的主键构造一颗B+树,同时叶子节点中存放的是整张表的行记录数据,聚集索引的叶子节点也称为数据页,索引文件就是...
2019-01-12 11:08:15
275
原创 索引(一)索引的本质
索引(一)索引的本质先看一个sqlSELECT count(*)FROM op_logWHERE method = "updateActivity"AND operator_id ="shinan"AND create_time > 1533819466000AND create_time < 1543819466000AND type=1;查询效率很慢:1...
2019-01-10 20:57:34
975
原创 服务器load高但是CPU使用率低
线上应用部署了两台服务器,项目发布之后跟踪线上服务器性能,发现一台load为3,一台load为1,四核服务器,有一台已经快到瓶颈了,因此紧急排查下原因1.TOP命令查看load和占用CPU比较大的进程,显示如下shift+c排序 占用最大的也就0.7% 1命名查看每个cpu的使用情况 基本上都处于空闲状态2.vmstat 2 5查看io情况procs -----------me...
2018-08-10 15:00:33
17907
2
原创 脚本启动钉钉机器人
背景:每周都需要催促团队成员撰写周报,因此想到在全员群里面设置定时通知机器人1.服务器创建目录 创建shell脚本mkdir shell -创建shell目录存放sh脚本vim dingding.sh -创建并且编写shell脚本填入以下内容:#!/bin/bashcurl 'https://oapi.dingtalk.com/robot/send?access_token=XXXX' -H '...
2018-06-30 23:17:29
2341
2
原创 AOP实现操作日志记录
一、设计: 操作日志记录 根据业务场景 一般是需要记录下数据修改更新的日志,查询类可以忽略。 所以需要对指定的某些方法进行记录。这块希望可以结合注解灵活操作,对于注解的方法进行日志记录操作日志表设计如下:CREATE TABLE `op_log` ( `id` bigint(20) NOT NULL COMMENT '主键', `operator` varchar(32) NOT NUL...
2018-06-22 16:36:19
6434
3
原创 Disruptor源码介绍(一)-RingBuffer
RingBuffer是Disruptor最重要的核心组件,可以理解为一个环形队列,用来存储事件,生产者往队列上面存放事件,消费者去读取。内部是如何实现的,我们来看下源码。1.类结构/** * Ring based store of reusable entries containing the data representing * an event being exchanged betwe...
2018-04-12 09:55:36
1612
原创 Disruptor简介
一.介绍Disruptor是java的并发框架,实现了无锁的队列,应用场景是“生产者-消费者”或“发布-订阅”模型的应用场合。可以拿JDK的BlockQueue来和Disruptor比较,总体上讲差不多,但是Disruptor的实现方式更为巧妙,性能更加的好主要体现在下面三点:1.根据消费者的依赖关系图,多播事件给多个消费者2.为事件提前分配内存3.可选择无锁二.重要概念Disruptor里面有一...
2018-04-08 16:44:50
481
原创 TestNG测试结果入库
需求:为了配合架构组做个单元测试数据的采集,需要将自动化集成测试的结果入库1.思路整理目前自动化测试工程采用的是TestNG框架执行集成测试,因此对这个框架做了下了解,看能不能基于这个框架搞事情,利用类似监听器,或者切面的方式,把测试结果入库。通过看官方文档,了解到TestNG提供了监听器,里面提供了多种方法, 符合使用的场景2.表设计CREATE TABLE `test_result` ( `...
2018-03-30 16:40:25
2261
5
原创 FULL GC隐患排查 优化
最近其它业务线反馈统一的国际化方案容易导致FULL GC,先简单说一下国际化方案:实现了一个filter,过滤所有的http请求,将请求头信息所带的语言环境存储到session里面,然后重新实现了response,对于文案统一采用编码的防范,response输出的时候将编码根据语言环境进行替换。 这里会有一个问题,如果是请求量比较大的应用,由于session的生命周期缘故,可能会导致...
2018-03-16 17:06:45
362
原创 git命名回滚到某个版本
背景:误操作将本地代码提交到了master分支当时想到了两个方法:1.把误提交的代码revert之后,重新再提交一次,但是这样会留下两次提交日志2.回滚代码到上一个版本,提交到remote分支,而且history里面也不会显示之前的提交所以选择了方法2,之后百度了下git回滚的命令,搜到了下面这两个命令:1.git reset --hard HEAD^ :回滚到上一个版本2.git push or...
2018-02-28 20:15:59
358
原创 成就系统实现(四)-测试和总结
完成架构设计之后,就开始进入了开发阶段,后续经过联调测试的调整,大概花了两个礼拜的时间,完成了开发和自测,代码已在github开源:https://github.com/caisl/achievement-system.git单元测试:@Test public void finishWelcomeAchievementTest() throws Exception { Or...
2018-02-27 20:09:19
1659
2
原创 记一次线上服务器load高问题定位和解决
1.top 查看load free空间还很大 应该不是GC导致的分析下面的进程,发现java进程占用了100%的CPU2.查找java进程下面的哪个线程占用CPU高ps -ef|grep java 获取PID 4381top -H -p 4381通过这个命令发现有一个线程占用了100%的CPU,所以导致load很高,一般占用100%CPU大部分原因是进程阻塞了。下一步跟踪一下这个线程 线程PID...
2018-02-23 15:05:50
2889
原创 SpringBoot服务端上传文件
最近做一个小程序服务端模块支持,小程序涉及到了文件上传,之前架构组提供了一个统一上传的接口给前端调用,因此没有服务端需要开发的部分。然而上线前一天,问题出现了,正式环境上传文件接口 不能提供给外网调用!需要通过服务端做中转,临危受命,紧急开发一个接口接收文件,然后通过httpClient调用架构组的接口上传文件数据。问题点如下:1.如果接收前端文件 需要跟前端约定 2.httpClient
2018-02-03 17:21:10
4877
原创 成就系统实现(三)-架构设计
1.技术选型之前上网找过一些关于成就系统设计的文档,推荐的都是事件驱动模型,因此底层设计也基于这个模型来做,由业务方产生可能触发成就的事件,统一放到一个队列里面,由线程去取队列里面的事件,进行分发处理。技术点:1.1 事件驱动模型1.2 disruptor 号称百万流量的一个高并发处理框架2.数据库设计2.1 成就包配置表CREATE TABLE `achievemen
2018-01-16 19:12:02
6944
2
原创 哨兵模式查询redis服务器ip
有时候我们需要用redis可视化软件比如RedisDesktopManager连接redis,查看存储的缓存情况,下面说明下如果根据代码配置文件里面的redis哨兵配置定位到具体的redis服务器IP一般常见的redis哨兵模式配置如下app.session.redis.server=sentinel1.redis.xxx.com:26379app.session.redis.
2018-01-11 19:06:59
6686
原创 成就系统实现(二)-功能分析
功能分析1. 成就的业务流程用户的某些操作触发成就->判断用户是否满足达成成就条件->达成进行奖励的发送 成就系统的业务流程大概分为这三步,每一步都可以细分里面的内部细节功能1.1 操作触发成就按照成就类型 抽象出具体哪些事件可能会触发1.2 用户达成成就触发的事件是否满足成就的条件,可能某一个事件会触发多个成就同时达成,或者某个成就完成了一部分,或者达成某个成就,成就一旦达成,就不会再被触发1.
2018-01-07 15:55:11
1632
原创 成就系统实现(一)-概述
需求在一个完整的业务流程链路中,用户的某种行为可能会触发成就的达成,如果成就达成了,推送一个弹窗让用户感知。第一版设计有11种可以达成的成就。每个成就都有对应的奖励。功能分析1.成就达成的条件分析,按照功能模块划分成就的类型 2.用户达成成就之后,之后同样的行为再也不会触发相同的成就 3.行为收集->成就条件判断->成就达成->奖励发放架构设计1.系统日均UV百万级别,成就
2017-12-30 15:36:10
3823
1
原创 MQ消息序列化失败排查
MQ消息序列化失败排查前几天项目环境跟别人联调消息的过程中 发现没有看到预期的消费消息的日志,因此开始找原因。1.确认消息生产方是否发了消息,找到消息生产方查看了服务器的日志,发现的确有发消息,根据msgId去消息控制平台查阅消息,显示消息已经被消费了。说明消息消费的配置也是没有问题。2.去订阅消息的服务器上面查找日志,看是否有异常日志的打印,按照条件搜索,果然找到了一个异常2017-11-22 1
2017-11-23 19:37:29
2535
1
原创 JAVA内存泄漏
JAVA内存泄漏介绍java内存泄漏的概念 线上遇到内存泄漏的解决方案1.概念如果内存空间中存在某些对象 ,拥有这两种特点,就可以判断为Java中的内存泄漏1.对象无用2.无用的对象还被引用着简单来说就是无用的内存不能被回收,就是内存泄露,长时间的内存泄漏会导致内存空间不够,最终导致OOM。2.发生原因对象都是有生命周期,有的长,有的短,长生命周期的对象A引用短生命周期的对象B,当对象B没有被程序
2017-11-07 19:10:44
288
原创 remote connection refused
remote connection refusedremote对程序员来说是定位问题的一件利器,本地启动remote连接远程服务器的时候遇到过下面的问题: 可能是下面几种原因导致的: - 服务器未配置端口 - remote配置的端口错误 - 端口被其他人占用
2017-03-22 14:14:59
779
原创 java字符串连接性能分析
字符串连接一向是比较常用的 ,异常日志输出或者是文字的组装等等,因此需要去思考选择哪种方法性能最高假设我们需要连接strA 和 strB 常用的几种字符串组装方式如下:1.String.format("%s%s",strA,strB)2.srtA + strB3.strA.concat(strB)4.new StringBuilder(strA).append(strB
2017-03-03 20:20:00
810
原创 IDEA远程调试配置
有时候我们需要远程调试,来分析定位问题的原因。IDEA中有remote插件,只需要创建一个新的配置就可以进行调试了。1.IDEA 工具栏2.添加一个新的remote配置3.填写name,调试服务器IP,调试端口.4.ip和端口需要配置正确 否则启动remote会提示连接拒绝调试的端口需要上服务器上面看是否配置,配置的具体端口号是多少,然后再填写。一般用tom
2016-11-05 10:56:04
538
原创 IDEA 快速入门
最近切换了IDE,从Myeclipse换成了IDEA,虽然前期对于软件操作,快捷键不太熟悉,但是坚持用下来之后,发现功能真心强大,所以能切换的尽量早换吧~下面是我觉得前期快速入门的方法 以及一些快捷键的使用。
2016-09-30 18:23:05
332
原创 Spring 事务
一.事务的概念事务指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败二.事务的特性(ACID)原子性:事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生一致性:事务前后数据的完整性必须保持一致隔离性:多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离持久性:一个事务一旦被提交,它对数据库中数据的
2016-08-30 20:13:42
356
Java设计模式综合应用场景
2014-06-23
https请求问题 Unrecognized SSL message
2016-01-04
java httpclient get请求拼接json数组到请求url后面
2015-11-25
https双向认证,加载证书报错
2015-11-11
TA创建的收藏夹 TA关注的收藏夹
TA关注的人