markdown
未读效果展示
折叠内容
折叠内容
在markdown中折叠一部分内容, 点击可以展开.
折叠代码
折叠代码
1234567public class HelloWorld { public static void main(String[] args) { System.out.println("HelloWorld"); }}
使用方式
使用html
1234<details><summary>折叠内容</summary>在markdown中折叠一部分内容, 点击可以展开.</details>
12345678<details><summary>折叠代码</summary> 代码块</details>
简单介绍下雪花算法, 以及Java版雪花算法的代码.
仅仅是一个最简单版本, 更深层次的指针回拨等. 相当于在开发过成功可以先使用.
尽量还是使用统一的分布式流水号生成系统, 保证流水号全局唯一.
雪花算法
10 0000000000 0000000000 0000000000 0000000000 0 00000 00000 000000000000
使用64位long型数字作为全局唯一id
1位 无意义 0
41位 时间戳
5位 机房id
5位 机器id
12位自增序号 表示同一时间同一机房同一机器生成的序列号
第一位为什么无意义
二进制中 第一位代表符号位, 默认 0 表示生成的序列号为正数
41位时间戳
41位最大能表示 2^41-1 的数字. 毫秒值 69.7年
(2^41-1)/1000/60/60/24
当时间大于69.7即时间戳差值大于 2199023255551, 会开始出现负值流水号
10位
机房id+机器id 2^10 1024台机器
1234567891011121314// 但是使用中不可能每部署一台机器都改下编号, 所以我做出以下改动// ...
近期遇到一个很久没有启动过的项目, 然后启动失败, 报 java.lang.NoClassDefFoundError, 现在记录问题排查情况.
错误代码
错误代码较长, 可以收缩, 直接看排查
123456789101112131415161718192021222324252627282930313233343536373839404142434445Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.][2020-04-10 13:26:11.478]-[main]-[]-[ERROR]-[org.springframework.boot.SpringApplication:821]-[Application run failed]org.springframework.context.ApplicationContextException: Unable to start web ...
issue
未读问题描述
部分项目log日志输出路径为 /data/log, 发现无法创建目录
错误信息: mkdir: cannot create directory ‘data’: Read-only file system
解决方式
关闭SPI
重启 按住CMD+R进入恢复模式
打开终端
终端输入命令:csrutil disable
挂载data
在用户目录(可以自己找一个目录下创建data)
12~ % > cd ~~ % > mkdir data
执行 sudo mount -uw / 重新挂载根目录
建立软链
1sudo ln -s /Users/liuzhihang/data /data
之后可以重启再打开spi了
修改matery主题首页显示视频为Bilibili视频
在Markdown插入Bilibili视频, 并设置大小.
首先找到分享嵌入代码
1<iframe src="//player.bilibili.com/player.html?aid=17963687&cid=29326684&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>
在markdown中使用嵌入代码
调整大小和居中等
iframe标签属性设置
123456<!-- 调整大小: width="xxx" height="xxx"--><iframe src="//player.bilibili.com/player.html?aid ...
Java进阶训练营学习笔记
课程: Java进阶训练营
老师: 中华石杉
邀请码: 二维码
使用方式
SET KEY VALUE TIME NX
DEL KEY
一般使用 NX, 只有在锁不存在的时候才加锁成功, 设置时间是为了锁永远得不到释放
存在问题及解决方法
A加锁, B释放
方法: Redisson 在tryLock时
1234567long threadId = Thread.currentThread().getId();protected String getLockName(long threadId) { return id + ":" + threadId;}// id 为 UUID
会将当前 uuId+线程id写入到锁信息中, unlock时会校验是否是当前线程
A lock锁住之后, 设置了时间, 但是在时间内未完成, 导致锁自动释放, 然后B获取锁同时进行操作
方法: Redisson 在lock时会启动异步线程, 自动延期, 时间为 lockWatchdogTimeout(默认30s)
1234 ...
Java进阶训练营学习笔记
课程: Java进阶训练营
老师: 中华石杉
邀请码: 二维码
作业:如果对自己的系统落地最终一致性事务,如何落地实现?
首先熟悉自己负责的业务, 熟悉系统间交互流程, 哪些可以异步, 哪些是必须同步
异步的时候要考虑是否需要一致性, 当前系统通知流程如图
如何落地最终一致性事务
根据课程思考最终一致性事务修改:
在收到交易请求, 成功时可以 commit half message
同时 需要实现 check方法, 供RocketMQ回调, 检查本地事务状态
在交易成功或失败时再进行commit或rollback
rollback消息 RocketMQ会定期删除
通知系统收到消息存储到本地并通知商户
问题
但是考虑到在这边系统完全没有必要增加事务, 因为发送消息到MQ是在交易结束后, 直接用一个字段判断状态, 然后用定时保证投递到MQ即可.
123RocketMQ的两段提交 half message执行流程根据流程结果: commit/rockback
可以改成
12执行流程RocketMQ send(普通消息)
在这边的使用场景中, 因为提交 ...
Java进阶训练营学习笔记
课程: Java进阶训练营
老师: 中华石杉
邀请码: 二维码
交易系统架构
请求流程:
请求首先到SLB(阿里云)经过负载均衡后, 到Nginx
Nginx做简单负载均衡后发给交易API系统, 4C8G * 5 ECS(阿里云)
交易会根据请求参数, 路由到各个子系统, 使用dubbo
子系统收到请求, 请求风控系统校验风控
请求应用中心获取应用参数 (appId, appKey等)
拼装报文,请求渠道系统
返回信息
日志报送流程
交易成功报送清结算, 报送数据中心
filebeat拉取日志, 报送kafka, 因filebeat升级 同时存在5.x和6.x 需要加中间一层, 之前是直接报logstash
logstash对数据进行过滤然后根据type 分别保送到 elasticsearch和redis
监控系统监控redis队列数据, 满足规则, 报警(发消息到通知系统)
监控系统对es数据进行过滤, 放到mysql, 用来展示商户, 渠道的交易变化等信息
kibana(直接用的kibana)提供给技术支持查询日志. es数据会定期删除, 保 ...
Java进阶训练营学习笔记
课程: Java进阶训练营
老师: 中华石杉
邀请码: 二维码
springcloud 通信原理
1. Eureka 集群
Eureka启动后, 会向其他节点注册, 相互直接视为 peer, 并互相同步注册信息.
2. 缓存机制
Eureka存在三个map: registry、readWriteCacheMap、readOnlyCacheMap
registry: CurrentHashMap 实时更新
readWriteCacheMap: Guava Cache/LoadingCache 也是实时更新
readOnlyCacheMap: CurrentHashMap 30秒同步 readWriteCacheMap一次
3. 服务注册
服务注册后每30s发送一次心跳(renew)
客户端每30秒请注册中心获取一次配置, 并存到本地内存中
注册中心会定时检查心跳, 连续没有3个回踢掉服务
Java进阶训练营学习笔记
课程: Java进阶训练营
老师: 中华石杉
邀请码: 二维码
操作流程图
1. 服务注册, 故障及下线
注册: provider和consumer同时在zk上注册临时节点, 同时consumer订阅zk /dubbo/**/providers provider地址, providers发生变化, zk自动推送给consumer
zk上结构如下
123ls /dubbo/cn.xxx.xxxService[consumers, routers, providers, configurators]
1[consumer://机器ip/接口?application=服务名&category=consumers&check=false&default.check=false&default.group=beta&default.timeout=5000&default.version=1.0.0&dubbo=2.6.2&interface=接口&methods=方法1,方法2& ...
背景
前段时间做了一个项目, 因为涉及到权限认证, 所以分别调研了 SpringSecurity 和 Apache Shiro. 最后选择使用了 SpringSecurity + JWT做权限认证, 现在项目已经结束, 总相关笔记.
项目下载地址 jwt-demo
使用JWT生成token
token存储在数据库中
使用 application/json 登录
使用手机号进行登录
URI动态拦截
配置过程
添加依赖
分别添加 SpringSecurity JWT 和 fastjson 依赖
123456789101112131415<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency><dependency> <groupId>io.jsonwebtok ...
Gitalk默认使用: location.pathname 作为 gitalk 的id, 但是location.path必须小于50位切换主题时, 每个主题使用的处理方式都不相同, 有可能会导致换了主题, 发现之前的评论不见了, 下面介绍使用MD5作为id, 同时在换主题时一定要修改这个id的规则.
Gitalk使用
使用Gitalk方法:
1234567891011var gitalk = new Gitalk({ clientID: 'GitHub Application Client ID', clientSecret: 'GitHub Application Client Secret', repo: 'GitHub repo', owner: 'GitHub repo owner', admin: ['GitHub repo owner and collaborators, only these guys can initialize github issues& ...