Skip to content

Commit 554fe8b

Browse files
committed
update note
1 parent cab4766 commit 554fe8b

5 files changed

Lines changed: 56 additions & 11 deletions

File tree

Java/JVM.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,11 @@ idea 设置 vm options:`-XX:MetaspaceSize=80m -XX:MaxMetaspaceSize=80m`
629629
-XX:+UseSerialGC 串行回收
630630
-XX:+PrintGCDetails 更详细的GC日志
631631

632+
-XX:MaxTenuringThreshold=0:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。
633+
634+
-XX:PermSize=64M JVM初始分配的永久代内存大小,用于存放类信息、静态变量、常量等。当应用需要动态产生大量类的时候,如jsp页面,需要将此参数设置大一点,避免永久代内存溢出。jdk1.8之后使用元空间代替永久代,此参数废弃;
635+
-XX:MaxPermSize=128M JVM最大允许分配的永久代内存;
636+
632637

633638

634639
## JVM调优工具
@@ -694,7 +699,7 @@ jstat -gcutil 4124
694699

695700
### jmap
696701

697-
查看堆内存快照。
702+
查看堆内存快照。查看进程中新生代、老年代、永久代的使用情况。
698703

699704
```java
700705
>jmap -heap 4124
@@ -746,3 +751,10 @@ PS Old Generation
746751
27776 interned Strings occupying 3262336 bytes.
747752
```
748753

754+
查询进程pid = 41843 存活的对象占用内存前100排序: `jmap -histo:live 41843 | head -n 100`
755+
756+
757+
758+
### 高cpu高内存分析
759+
760+
[线上问题排查](https://blog.csdn.net/baiye_xing/article/details/90483169)

中间件/RabbitMQ.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535

3636
[RabbitMQ发送邮件代码](https://zhuanlan.zhihu.com/p/145908317)
3737

38+
[线上rabbitmq问题](https://juejin.im/post/6844904088212094983#heading-0)
39+
3840
## 简介
3941

4042
RabbitMQ是一个由erlang开发的消息队列。消息队列用于应用间的异步协作。
@@ -183,7 +185,7 @@ rabbitTemplate.setReturnCallback(returnCallback);
183185

184186
有可能消费者收到消息还没来得及处理MQ服务就宕机了,导致消息丢失。因为消息者默认采用自动ack,一旦消费者收到消息后会通知MQ Server这条消息已经处理好了,MQ 就会移除这条消息。
185187

186-
解决方法:消费者设置为手动确认消息。消费者处理完逻辑之后再通知 MQ Server,消息已经成功消费,可以删除。当消息者消费失败的时候,MQ 会重发消息
188+
解决方法:消费者设置为手动确认消息。消费者处理完逻辑之后再给broker回复ack,表示消息已经成功消费,可以从broker中删除。当消息者消费失败的时候,给broker回复nack,根据配置决定重新入队还是从broker移除,或者进入死信队列。只要没收到消费者的 acknowledgment,broker 就会一直保存着这条消息,但不会 requeue,也不会分配给其他 消费者
187189

188190
消费者设置手动ack:
189191

@@ -210,6 +212,8 @@ spring.rabbitmq.listener.simple.acknowledge-mode=manual
210212
}
211213
```
212214

215+
当消息消费失败时,消费端给broker回复nack,如果consumer设置了requeue为false,则nack后broker会删除消息或者进入死信队列,否则消息会重新入队。
216+
213217
### 持久化
214218

215219
如果RabbitMQ服务异常导致重启,将会导致消息丢失。RabbitMQ提供了持久化的机制,将内存中的消息持久化到硬盘上,即使重启RabbitMQ,消息也不会丢失。
@@ -416,4 +420,10 @@ pull模式主要是通过channel.basicGet方法来获取消息,示例代码如
416420
GetResponse response = channel.basicGet(QUEUE_NAME, false);
417421
System.out.println(new String(response.getBody()));
418422
channel.basicAck(response.getEnvelope().getDeliveryTag(),false);
419-
```
423+
```
424+
425+
426+
427+
## 消息积压
428+
429+
[Rabbitmq消息积压](http://luxiaobing.com/2019/12/07/RabbitMq%E6%B6%88%E6%81%AF%E7%A7%AF%E5%8E%8B/)

其他/code.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class Singleton {
3737
}
3838
private Singleton() {}
3939
public static Singleton getSingleton() {
40-
return SingletonHolder.instance;// 这里将导致InstanceHolder类被初始化
40+
return SingletonHolder.instance;// 这里将导致SingletonHolder类被初始化
4141
}
4242
}
4343
```

其他/note.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,10 +239,25 @@ select、poll和epoll都是IO多路复用的机制。
239239

240240
## 超卖问题
241241

242+
先到数据库查询库存,在减库存。不是原子操作,会有超卖问题。
243+
242244
通过加排他锁解决该问题。
243245

244246
- 开始事务。
245247
- 查询库存,并显式的设置排他锁:SELECT * FROM table_name WHERE … FOR UPDATE
246248
- 生成订单。
247249
- 去库存,update会隐式的设置排他锁:UPDATE products SET count=count-1 WHERE id=1
248-
- commit,释放锁。
250+
- commit,释放锁。
251+
252+
也可以通过乐观锁实现。使用版本号实现乐观锁。
253+
254+
假设此时version = 100, num = 1; 100个线程进入到了这里,同时他们select出来版本号都是version = 100。
255+
256+
然后直接update的时候,只有其中一个先update了,同时更新了版本号。
257+
258+
那么其他99个在更新的时候,会发觉version并不等于上次select的version,就说明version被其他线程修改过了,则放弃此次update,重试直到成功。
259+
260+
```mysql
261+
select version from goods WHERE id= 1001
262+
update goods set num = num - 1, version = version + 1 WHERE id= 1001 AND num > 0 AND version = @version(上面查到的version);
263+
```

数据库/mysql进阶.md

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,21 @@ Java JUC中的atomic包就是乐观锁的一种实现,AtomicInteger 通过CAS
456456

457457
[分库分表](https://blog.csdn.net/weixin_44062339/article/details/100491744)
458458

459-
垂直划分数据库是根据业务进行划分,例如将shop库中涉及商品、订单、用户的表分别划分出成一个库,通过降低单库的大小来提高性能,但这种方式并没有解决高数据量带来的性能损耗。同样的,分表的情况就是将一个大表根据业务功能拆分成一个个子表,例如用户表可根据业务分成基本信息表和详细信息表等
460-
优点:拆分后业务清晰,达到专库专用;便于维护
461-
缺点:不解决数据量大带来的性能损耗,读写压力依旧很大;不同的业务无法跨库关联(join),只能通过业务来关联
459+
垂直划分数据库是根据业务进行划分,例如将shop库中涉及商品、订单、用户的表分别划分出成一个库,通过降低单库的大小来提高性能,但这种方式并没有解决高数据量带来的性能损耗。同样的,分表的情况就是将一个大表根据业务功能拆分成一个个子表,例如商品基本信息和商品描述,商品基本信息一般会展示在商品列表,商品描述在商品详情页,可以将商品基本信息和商品描述拆分成两张表
460+
优点:行记录变小,页可以存放更多记录,在查询时减少I/O次数
461+
缺点:主键出现冗余,需要管理冗余列;会引起表连接JOIN操作(增加CPU开销),可以通过在业务服务器上进行join来减少数据库压力;依然存在单表数据量过大的问题(需要水平拆分)
462462

463463
水平划分是根据一定规则,例如时间或id序列值等进行数据的拆分。比如根据年份来拆分不同的数据库。每个数据库结构一致,但是数据得以拆分,从而提升性能。
464-
优点:单库(表)的数据量得以减少,提高性能;提高了系统的稳定性和负载能力;切分出的表结构相同,程序改动较少
465-
缺点:数据分片在扩容时需要迁移;维护量增大;无法跨库关联
464+
465+
优点:单库(表)的数据量得以减少,提高性能;切分出的表结构相同,程序改动较少
466+
467+
缺点:
468+
469+
- 分片事务一致性难以解决
470+
- 跨节点Join性能差,逻辑复杂
471+
- 数据分片在扩容时需要迁移
472+
473+
库内分表,仅仅是单纯的解决了单一表数据过大的问题,由于没有把表的数据分布到不同的机器上,因此对于减轻MySQL服务器的压力来说,并没有太大的作用,大家还是竞争同一个物理机上的IO、CPU、网络,这个可以通过分库来解决。
466474

467475

468476

@@ -805,7 +813,7 @@ update user set name = 'tyson' where id = 1;
805813

806814
为什么记录完 redo log,不直接提交,先进入prepare状态?
807815

808-
假设先写 redo log 直接提交,然后写 binlog,写完 redo log 后,机器挂了,binlog 日志没有被写入,那么机器重启后,这台机器会通过 redo log 恢复数据,但是这个时候 bingog 并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。
816+
假设先写 redo log 直接提交,然后写 binlog,写完 redo log 后,机器挂了,binlog 日志没有被写入,那么机器重启后,这台机器会通过 redo log 恢复数据,但是这个时候 binlog 并没有记录该数据,后续进行机器备份的时候,就会丢失这一条数据,同时主从同步也会丢失这一条数据。
809817

810818
假设写完了 binlog,机器异常重启了,由于没有 redo log,本机是无法恢复这一条记录的,但是 binlog 又有记录,那么和上面同样的道理,就会产生数据不一致的情况。
811819

0 commit comments

Comments
 (0)