网络io模型

网络io模型

对于io模型这块内容之前基本完全没有接触过,有了些许了解之后还是很困昏,select、poll、epoll的关系以及服务器ngnix、apache的工作机制,还有JAVA NIO、BIO、AIO这么多的概念混杂起来实在是不好理解,想稍微梳理一下。 网络IO模型 网络IO的本质是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作 IO其实我们并不陌生,站在操作系统的角度上说,io一般指访问磁盘数据,可以分为两步,以read操作举例的话: 第一阶段:等待数据准备 (Waiting for the data to be ready)。 第二阶段:将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)。 而网络IO也是如此,只不过它是读取的不是磁盘,而是socket: 第一步:通常涉及等待网络上的数据分组到达,然后被复制到内核的某个缓冲区。 第二步:把数据从内核缓冲区复制到应用进程缓冲区。 在理解网络IO模型之前,我们得先准备些IO模型的基础知识 IO模型 Unix 有五种 I/O 模型: 阻塞IO(bloking IO) 非阻塞IO(non-blocking IO) 多路复用IO(multiplexing IO) 信号驱动式IO(signal-driven IO) 异步IO(asynchronous IO) 每个 IO 模型都有自己的使用模式,它们对于特定的应用程序都有自己的优点。下面提供一个简单的图片以供了解。 image 阻塞式 IO 应用进程被阻塞,直到数据复制到应用进程缓冲区中才返回。 应该注意到,在阻塞的过程中,其它程序还可以执行,因此阻塞不意味着整个操作系统都被阻塞。因为其他程序还可以执行,因此不消耗 CPU 时间,这种模型的 CPU 利用率效率会比较高。 下图中,recvfrom 用于接收 Socket 传来的数据,并复制到应用进程的缓冲区 buf 中。这里把 recvfrom() 当成系统调用。 [图片上传失败...(image-111ada-1538122299754)] 非阻塞式 IO 应用进程执行系统调用之后,内核返回一个错误码。应用进程可以继续执行,但是需要不断的执行系统调用来获知 I/O 是否完成,这种方式称为轮询(polling)。 由于 CPU 要处理更多的系统调用,因此这种模型的 CPU 利用率是比较低的。 [图片上传失败...(image-76babc-1538122299754)] 多路复用IO 由于阻塞式IO通过轮询得到的只是一个IO任务是否完成,而可能有多个任务在同时进行,因此就想到了能否轮询多个IO任务的状态,只要有任何一个任务完成,就去处理它。这就是所谓的IO多路复用。LINUX下具体的实现方式就是select、poll、epoll。 这种机制可以让单个进程具有处理多个 IO 事件的能力。

MySQL中 datetime类型精度提示:需要精确到微秒请不要直接使用datetime类型。

MySQL中 datetime类型精度提示:需要精确到微秒请不要直接使用datetime类型。

MySQL中的默认的datatime类型所控制的精度是不包含到毫秒的,它即包含date,也包含time,即:'YYYY-MM-DD hh:mm:ss' , 取值范围 为'1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' 那么问题来了: 1. 如果插入的数据带有毫秒,那么会成功吗?如果成功,毫秒部分如何处理?是直接丢弃还是舍入? 2. 如果想让数据更加精确,包含1-6位毫秒,怎么办? 对于问题1的答案是:会成功,毫秒部分不会直接丢弃,会舍入(rounding),测试如下: mysql> create table mqst1(id int, createtime datetime); Query OK, 0 rows affected (0.07 sec) mysql> insert into mqst1 values(1,'2021-10-01 21:08:08.123'); Query OK, 1 row affected (0.01 sec) mysql> insert into mqst1 values(2,'2021-10-01 21:20:08.678'); Query OK, 1 row affected (0.01 sec) mysql> select * from mqst1; +------+---------------------+ | id | createtime | +------+---------------------+ | 1 | 2021-10-01 21:08:08 | | 2 | 2021-10-01 21:20:09 | +------+---------------------+ 2 rows in set (0.00 sec) 可以看到,插入是成功的,毫秒部分被4舍5入了。 对于问题2的答案是可以使用datetime(n),其中n最大可以是6, 如果是0的话相当于datatime. 测试如下: mysql> create table mqst2(id int, createtime datetime(6)); Query OK, 0 rows affected (0.03 sec) mysql> insert into mqst2 values(1,'2021-10-01 21:08:08.123'); Query OK, 1 row affected (0.04 sec) mysql> insert into mqst2 values(1,'2021-10-01 21:08:08.123123'); Query OK, 1 row affected (0.01 sec) mysql> select * from mqst2; +------+----------------------------+ | id | createtime | +------+----------------------------+ | 1 | 2021-10-01 21:08:08.123000 | | 1 | 2021-10-01 21:08:08.123123 | +------+----------------------------+ 2 rows in set (0.00 sec) 参考资料: MySQL :: MySQL 5.7 Reference Manual :: 11.2.7 Fractional Seconds in Time Values

干货|一篇文章带你学习分布式事务

干货|一篇文章带你学习分布式事务

一. 事务 1.1 什么是事务 数据库事务(简称:事务,Transaction)是指数据库执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。 事务拥有以下四个特性,习惯上被称为ACID特性: 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态是指数据库中的数据应满足完整性约束。除此之外,一致性还有另外一层语义,就是事务的中间状态不能被观察到(这层语义也有说应该属于原子性)。 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行,如同只有这一个操作在被数据库所执行一样。 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。在事务结束时,此操作将不可逆转。 1.2 本地事务 起初,事务仅限于对单一数据库资源的访问控制: 架构服务化以后,事务的概念延伸到了服务中。倘若将一个单一的服务操作作为一个事务,那么整个服务操作只能涉及一个单一的数据库资源: 这类基于单个服务单一数据库资源访问的事务,被称为本地事务(Local Transaction)。 二. 分布式事务应用架构 本地事务主要限制在单个会话内,不涉及多个数据库资源。但是在基于SOA(Service-Oriented Architecture,面向服务架构)的分布式应用环境下,越来越多的应用要求对多个数据库资源,多个服务的访问都能纳入到同一个事务当中,分布式事务应运而生。 最早的分布式事务应用架构很简单,不涉及服务间的访问调用,仅仅是服务内操作涉及到对多个数据库资源的访问。 当一个服务操作访问不同的数据库资源,又希望对它们的访问具有事务特性时,就需要采用分布式事务来协调所有的事务参与者。 对于上面介绍的分布式事务应用架构,尽管一个服务操作会访问多个数据库资源,但是毕竟整个事务还是控制在单一服务的内部。如果一个服务操作需要调用另外一个服务,这时的事务就需要跨越多个服务了。在这种情况下,起始于某个服务的事务在调用另外一个服务的时候,需要以某种机制流转到另外一个服务,从而使被调用的服务访问的资源也自动加入到该事务当中来。下图反映了这样一个跨越多个服务的分布式事务: 如果将上面这两种场景(一个服务可以调用多个数据库资源,也可以调用其他服务)结合在一起,对此进行延伸,整个分布式事务的参与者将会组成如下图所示的树形拓扑结构。在

Locale深度解析

Locale深度解析

摘要 Locale是日常开发中比较容易忽视的技术点。特别是开发一些只做国内市场,只有中文的项目时,Locale可能就直接被忽视了。而且在项目提出多语言支持的时候,因为没有很好的理解,可能给自己埋了很多坑。 什么是Locale 其实java.util.Locale的Java Doc有很详细的解释,我就不过多解释。 A Locale object represents a specific geographical, political, or cultural region. An operation that requires a Locale to perform its task is called locale-sensitive and uses the Locale to tailor information for the user. 主要记住Locale实例包括以下信息就可以了。在多年的开发经验中,script和variant基本没有用到。就不过多介绍。 language script country (region) variant lanugage ISO 639 alpha-2 or alpha-3 language code 在实际使用中,基本我们碰不到3位字母表示的语言。 country ISO 3166 alpha-2 country code or UN M.49 numeric-3 area code. 同样实际使用中,基本使用2位字母表示的国家 scirpt 和 variant IANA Language Subtag Registry 定义了完整列表。 感觉script是地区的别称,variant是方言。了解一下就好。 在实际使用中,大部分同学第一反应可能是会写出以下Locale。 zh_CN en_US ja_JP 如果你也是只想到这些,请打开你的浏览器->开发者工具->控制台中输入以下js window.navigator.language 浏览器为中文,你又在国内。输出结果就是zh-CN 然后如果重新你设置浏览器语言,比如设置成英文。再执行一下,输出结果是en-CN What?? en-CN?? 这是什么鬼? 首先通过这个Locale,我们可以知道country,是和你实际在哪个地区有关。 那该怎么处理? 后面详细说怎么应用。 应用场景 Locale的使用场景基本就是根据不同国家和语言,进行不同的显示。实际经验以下2点为主。 多语言 (下文会详细说明) 金额显示。 日期格式显示。 以金额显示为例,如果没有类似开发经验的话,你可以为会想,金额还有不同的格式。一般不都是 1,000,000.00。那你就错了。举两个例子。 日语。日本人金额是不带小数点的。 法语。法语中千位分隔符为空格,小数点为逗号。比如 1 000 000,00 正确理解Locale,并正确使用可以写出既规范,又简练,质量又高的代码。而不是见招拆招,每个语言写一个自己的实现。 创建Locale 实例的正确姿势 使用正确的姿势创建非常重要,这在后面Spring里应用部分非常重要。 以下这段代码是我见过最多的创建方式。 Locale locale = n

指令寄存器和程序计数器的区别

指令寄存器和程序计数器的区别

1、程序存储器(program storage) 在计算机的主存储器中专门用来存放程序、子程序的一个区域。 2、指令寄存器(IR ):用来保存当前正在执行的一条指令。当执行一条指令时,先把它从内存取到数据寄存器(DR)中,然后再传送至IR。指令划分为操作码和地址码字段,由二进制数字组成。为了执行任何给定的指令,必须对操作码进行测试,以便识别所要求的操作。指令译码器就是做这项工作的。指令寄存器中操作码字段的输出就是指令译码器的输入。操作码一经译码后,即可向操作控制器发出具体操作的特定信号。 3、程序计数器(PC):为了保证程序(在操作系统中理解为进程)能够连续地执行下去,CPU必须具有某些手段来确定下一条指令的地址。而程序计数器正是起到这种作用,所以通常又称为指令计数器。在程序开始执行前,必须将它的起始地址,即程序的一条指令所在的内存单元地址送入PC,因此程序计数器(PC)的内容即是从内存提取的第一条指令的地址。当执行指令时,CPU将自动修改PC的内容,即每执行一条指令PC增加一个量,这个量等于指令所含的字节数,以便使其保持的总是将要执行的下一条指令的地址。由于大多数指令都是按顺序来执行的,所以修改的过程通常只是简单的对PC加1。 当程序转移时,转移指令执行的最终结果就是要改变PC的值,此PC值就是转去的地址,以此实现转移。有些机器中也称PC为指令指针IP(Instruction Pointer) 4、地址寄存器:用来保存当前CPU所访问的内存单元的地址。由于在内存和CPU之间存在着操作速度上的差别,所以必须使用地址寄存器来保持地址信息,直到内存的读/写操作完成为止 。? 当CPU和内存进行信息交换,即CPU向内存存/取数据时,或者CPU从内存中读出指令时,都要使用地址寄存器和数据缓冲寄存器。同样,如果我们把外围设备的设备地址作为像内存的地址单元那样来看待,那么,当CPU和外围设备交换信息时,我们同样使用 地址寄存器和数据缓冲寄存器 基本上定义就是区别和应用。

联系我们

联系电话

4000-640-466

联系邮箱

service@f-li.cn

办公地址

上海黄浦区外滩源1号

谢谢,您的信息已成功发送。
请填写信息。