mysql日志
redo log(重做日志)
binlog(归档日志)
undolog (回滚日志)
redo log(重做日志)
binlog(归档日志)
undolog (回滚日志)
什么是分布式ID
在我们系统数据量不大的时候,单库单表完全可以支撑现有系统,数据再大一点搞个MySQL主从同步读写分离也能对付。
但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID。
Java虚拟机是Java平台的基石。它是技术的组成部分,负责硬件和操作系统的独立性,编译代码的小巧大小以及保护用户免受恶意程序侵害的能力。
Java虚拟机是抽象的计算机。像真正的计算机一样,它具有指令集,并在运行时操作各种内存区域。使用虚拟机实现编程语言是相当普遍的。最知名的虚拟机可能是UCSD Pascal的P代码计算机。
网络通信中,最底层的就是内核中的网络 I/O 模型了。
随着技术的发展,操作系统内核的网络模型衍生出了五种 I/O 模型,《UNIX 网络编程》一书将这五种 I/O 模型分为
阻塞式 I/O
、非阻塞式 I/O
、I/O 复用
、信号驱动式 I/O
和异步 I/O
。每一种 I/O 模型的出现,都是基于前一种 I/O 模型的优化升级。
代码工具:jmh JMH是一个Java工具,用于构建、运行和分析nano/micro/mili/macro基准,这些基准是用Java和其他针对JVM的语言编写的。
Code Tools: jmh JMH is a Java harness for building, running, and analysing nano/micro/milli/macro benchmarks written in Java and other languages targetting the JVM.
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.23</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.23</version>
</dependency>
Java 性能调优不像是学一门编程语言,无法通过直线式的思维来掌握和应用,它对于工程师的技术广度和深度都有着较高的要求。
互联网时代,一个简单的系统就囊括了应用程序、数据库、容器、操作系统、网络等技术,线上一旦出现性能问题,就可能要你协调多方面组件去进行优化,这就是技术广度;而很多性能问题呢,又隐藏得很深,可能因为一个小小的代码,也可能因为线程池的类型选择错误…可归根结底考验的还是我们对这项技术的了解程度,这就是技术深度。
我们调优的对象不是单一的应用服务,而是错综复杂的系统。应用服务的性能可能与操作系统、网络、数据库等组件相关,所以我们需要储备计算机组成原理、操作系统、网络协议以及数据库等基础知识。具体的性能问题往往还与传输、计算、存储数据等相关,那我们还需要储备数据结构、算法以及数学等基础知识。
如果你们公司做的是 12306 网站,不做系统性能优化就上线,试试看会是什么情况。
一款线上产品如果没有经过性能测试,那它就好比是一颗定时炸弹,你不知道它什么时候会出现问题,你也不清楚它能承受的极限在哪儿。
好的系统性能调优不仅仅可以提高系统的性能,还能为公司节省资源
Actor模型:面向对象原生的并发模型
Actor模型是高性能网络中处理并行任务的一种方法,解决并发问题的利器
Actor模型本质上是一种计算模型,基本的计算单元称为 Actor,在 Actor 模型里,一切都是 Actor,所有的计算都是在 Actor 中执行的,并且 Actor 之间是完全隔离的,不会共享任何变量。
Actor模型解决了 传统编程假设与现代多线程、多CPU架构的现实之间的不匹配问题。
- 消息传递的使用避免了锁和阻塞。
- Actor能够优化地处理错误情况。
Java 语言本身并不支持 Actor 模型,所以如果你想在 Java 语言里使用 Actor 模型,就需要借助第三方类库,目前能完备地支持 Actor 模型而且比较成熟的类库就是 Akka。
Akka is a toolkit and runtime for building highly concurrent, distributed, and fault-tolerant event-driven applications on the JVM. Akka can be used with both Java and Scala. This guide introduces Akka by describing the Java version of the Hello World example. If you prefer to use Akka with Scala, switch to the Akka Quickstart with Scala guide.
Actors are the unit of execution in Akka. The Actor model is an abstraction that makes it easier to write correct concurrent, parallel and distributed systems. The Hello World example illustrates Akka basics. Within 30 minutes, you should be able to download and run the example and use this guide to understand how the example is constructed. This will get your feet wet, and hopefully inspire you to dive deeper into the wonderful sea of Akka!
Akka是Actor模型的一种实现
Actor模型解决了 传统编程假设与现代多线程、多CPU架构的现实之间的不匹配问题。
- 消息传递的使用避免了锁和阻塞。
- Actor能够优化地处理错误情况。
Usage of message passing avoids locking and blocking.
Actors handle error situations gracefully
** OOP在构建苛刻需求的分布式系统会遇到的问题 **
- 并发情况下封装导致效率问题和死锁问题。
- 并发时共享内存失效(CPU缓存失效导致)导致效率低的问题。
- 调用栈导致的后台线程在异常时的通信问题以及后续问题。
- The challenge of encapsulation
- The illusion of shared memory on modern computer architectures
- The illusion of a call stack
java -XX:+PrintFlagsFinal -version | grep HeapSize # 查看堆内存配置的默认值
jmap -heap pid
没有万能的JVM参数配置,如果有的话就可能是内存给大点,代码写好点,其它用默认 (JVM已经优化了很多参数)
2C4G容器常见配置
-server
-Xcomp
-Xmx2g
-Xms2g
-Xmn800m
-XX:MetaspaceSize=512m
-XX:MaxMetaspaceSize=512M
-Xss256k
-XX:+DisableExplicitGC
-XX:+UseConcMarkSweepGC
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:LargePageSizeInBytes=128m
-XX:+UseFastAccessorMethods
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=75
-XX:+HeapDumpOnOutOfMemoryError
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
多线程设计模式是前人解决并发问题的经验总结,当我们试图解决一个并发问题时,首选方案往往是使用匹配的设计模式,这样能避免走弯路。
大家都熟悉设计模式,所以使用设计模式还能提升方案和代码的可理解性。
避免共享的设计模式
Immutability 模式
、Copy-on-Write 模式
和线程本地存储模式
本质上都是为了避免共享,只是实现手段不同而已。
多线程版本IF的设计模式
Guarded Suspension 模式
和Balking 模式
都可以简单地理解为“多线程版本的 if”,但它们的区别在于前者会等待 if 条件变为真,而后者则不需要等待。
三种最简单的分工模式
Thread-Per-Message模式
、Worker Thread 模式
和生产者-消费者模式
是三种最简单实用的多线程分工方法
解决并发问题,其实最简单的办法就是让共享变量只有读操作,而没有写操作。
不变性(Immutability)模式。所谓不变性,简单来讲,就是对象一旦被创建之后,状态就不再发生变化。换句话说,就是变量一旦被赋值,就不允许修改了(没有写操作);没有修改操作,也就是保持了不变性。
Java SDK 里很多类都具备不可变性。例如经常用到的 String 和 Long、Integer、Double 等基础类型的包装类都具备不可变性,这些对象的线程安全性都是靠不可变性来保证的。仔细翻看这些类的声明、属性和方法,你会发现它们都严格遵守不可变类的三点要求:类和属性都是 final 的,所有方法均是只读的。
Java所有的基础类型的包装类都不适合做锁,因为它们内部用到了享元模式,这会导致看上去私有的锁,其实是共有的。
使用 Immutability 模式的注意事项在使用 Immutability 模式的时候,需要注意以下两点:
- 对象的所有属性都是 final 的,并不能保证不可变性;
- 不可变对象也需要正确发布。
在使用 Immutability 模式的时候一定要确认保持不变性的边界在哪里,是否要求属性对象也具备不可变性。
Foo对象是不变的,但是Foo对象的属性是可以变化的class Foo{ int age=0; int name="abc"; } final class Bar { final Foo foo; void setAge(int a){ foo.age=a; } }