你要如何衡量你的人生

坚持,努力,让好事发生

首先说一下为什么要做微服务。
当你有 100台MySQL数据库,1000个Redis,1000个ES,1万个容器,部署着100种服务。

无论是微服务、SOA、还是 RPC 架构,它们都是分布式服务架构,都需要实现服务之间的互相通信,我们通常把这种通信统称为 RPC 通信。

RPC(Remote Process Call),即远程服务调用,是通过网络请求远程计算机程序服务的通信技术。RPC 框架封装好了底层网络通信、序列化等技术,我们只需要在项目中引入各个服务的接口包,就可以实现在代码中调用 RPC 服务同调用本地方法一样。

小型的项目用什么语言都行,爱用什么用什么。但是,真正的企业级架构就不一样了,其中并不仅仅只是 RESTful API 或 RPC,还有各种配套设施和控制系统,比如:应用网关,服务发现、配置中心、健康检查、服务监控、服务治理(熔断、限流、幂等、重试、隔离、事务补偿)、Tracing监控、SOA/ESB、CQRS、EDA……

本文不会告诉你必须用什么,但是会告诉你两者的优缺点。

rest 以 springcloud为例,rpc以dubbo为例。

从性能上来讲,在数据量小(单个请求小于20K)并发大的场景下,rpc的性能比restful api的性能要好。
从上手、使用、维护 方面来说,springcloud更容易上手、维护。

各组件配置使用运行流程:
1、请求统一通过API网关(Zuul)来访问内部服务.
2、网关接收到请求后,从注册中心(Eureka)获取可用服务
3、由Ribbon进行均衡负载后,分发到后端具体实例
4、微服务之间通过Feign进行通信处理业务
5、Hystrix负责处理服务超时熔断
6、Turbine监控服务间的调用和熔断相关指标

springcloud提供了微服务所需的全套组件,降低了架构和开发成本,解决了微服务的多个痛点问题。具体如下:

  1. 注册中心
  2. 配置中心
  3. 服务间的调用方式
  4. 链路追踪
  5. 服务的限流、降级、熔断

如果使用dubbo,配置中心、分布式跟踪这些内容都需要自己去集成,无形中增加了难度。

References

[1] 微服务架构的基础框架选择:Spring Cloud还是Dubbo?
[2] 比较spring cloud和dubbo,各自的优缺点是什么
[3] 中小型互联网公司微服务实践-经验和教训
[4] SpringBoot和SpringCloud为什么会那么火?对开发有哪些帮助?
[5] 项目中为什么首先spring cloud,而不是dubbo
[6] Microservices-微服务原文

各组件配置使用运行流程:
1、请求统一通过API网关(Zuul)来访问内部服务.
2、网关接收到请求后,从注册中心(Eureka)获取可用服务
3、由Ribbon进行均衡负载后,分发到后端具体实例
4、微服务之间通过Feign进行通信处理业务
5、Hystrix负责处理服务超时熔断
6、Turbine监控服务间的调用和熔断相关指标

springcloud提供了微服务所需的全套组件,降低了架构和开发成本,解决了微服务的多个痛点问题。具体如下:

  1. 注册中心
  2. 配置中心
  3. 服务间的调用方式
  4. 链路追踪
  5. 服务的限流、降级、熔断

References

[1] spring-cloud
[2] springcloud中文网
[3] springcloud(一):大话Spring Cloud-纯洁的微笑
[4] 史上最简单的 SpringCloud 教程 | 终章-方志朋
[5] Spring Cloud 从入门到精通
[6] Spring Cloud中国社区

orientdb启动后可以在 http://localhost:2480 打开前端管理界面操作,也可以在shell里操作

orientdb的很多语句很像mysql和neo4j,学习的时候可以用来对比

常用语句

orientdb mysql
连接数据库 CONNECT remote:127.0.0.1 root root mysql -u root -p root
查看所有数据库 LIST DATABASES show databases
创建数据库 CREATE DATABASE remote:127.0.0.1/db_test_wkq root root create database db_test_wkq
使用某个数据库 CONNECT remote:127.0.0.1/db_test_wkq root root use db_test_wkq
查询节点类型(表)个数 LIST CLASSES
select expand(classes) from metadata:schema
show tables
创建某类节点 CREATE CLASS TestVertex extends V create table table1
查看某个类型的结构 INFO CLASS OUser desc table1
查看某个类型的数据 BROWSE CLASS OUser select * from OUser limit 20
      CREATE DATABASE <database-url> [<user>] [<password>] [<storage-type>] [<db-type>] [<[options]>]

创建数据库 CREATE DATABASE PLOCAL:/usr/local/orientdb/databases/db_test_wkq
CREATE DATABASE remote:127.0.0.1/db_test_wkq root root plocal graph

阅读全文 »

在日常的开发中遇到1个问题
我们要部署一个系统给甲方,但是又不想让甲方知道我们的代码是怎么写的,需要Java的代码如果要加密不让别人获取到有什么办法?

研发人员都知道我们写的Java代码是.java文件,然后被编译成.class文件后,JVM可以解释执行class文件。
我们写的Java代码不会给甲方,给甲方的是编译好的包,也就是一堆class文件,但是class文件也有可能被反编译,获取到.java文件。
想了很久,通过对class文件加密,在使用时通过自定义的ClassLoader加载class,然后在自定义的ClassLoader里再增加一个验证秘钥方法,通过秘钥才能继续执行方法加载class文件。

(1) JVM加载class过程

java-class-life-cycle

一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)七个阶段。

其中验证、准备、解析三个部分统称为连接(Linking)。

加载、验证、准备、初始化和卸载这五个阶段的顺序是确定,而解析阶段则不一定:它在某些情况下可以在初始化阶段之后再开始。

(1.1) 加载

Class文件又称字节码文件,一种二进制文件,它是由某种语言经过编译而来,注意这里并不一定是Java语言,还有可能是 Scala、Groovy 等,Class文件运行在Java虚拟机上。
Java虚拟机不与任何一种语言绑定,它只与Class文件这种特定的二进制文件格式所关联。

加载,是指查找字节流,并且据此创建类的过程。

在加载阶段,Java虚拟机需要完成以下三件事情:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。
  2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。
阅读全文 »

秒杀系统

秒杀其实主要解决两个问题,一个是并发读,一个是并发写

并发读的核心优化理念是尽量减少用户到服务端来“读”数据,或者让他们读更少的数据;并发写的处理原则也一样,它要求我们在数据库层面独立出来一个库,做特殊的处理。另外,我们还要针对秒杀系统做一些保护,针对意料之外的情况设计兜底方案,以防止最坏的情况发生。

所谓“稳”,就是整个系统架构要满足高可用,流量符合预期时肯定要稳定,就是超出预期时也同样不能掉链子,你要保证秒杀活动顺利完成,即秒杀商品顺利地卖出去,这个是最基本的前提。
然后就是“准”,就是秒杀 10 台 iPhone,那就只能成交 10 台,多一台少一台都不行。一旦库存不对,那平台就要承担损失,所以“准”就是要求保证数据的一致性。
最后再看“快”,“快”其实很好理解,它就是说系统的性能要足够高,否则你怎么支撑这么大的流量呢?不光是服务端要做极致的性能优化,而且在整个请求链路上都要做协同的优化,每个地方快一点,整个系统就完美了。

所以从技术角度上看“稳、准、快”,就对应了我们架构上的高可用、一致性和高性能的要求,我们的专栏也将主要围绕这几个方面来展开,具体如下。
秒杀涉及大量的并发读和并发写,因此支持高并发访问这点非常关键。本专栏将从设计数据的动静分离方案、热点的发现与隔离、请求的削峰与分层过滤、服务端的极致优化这 4 个方面重点介绍。
秒杀中商品减库存的实现方式同样关键。可想而知,有限数量的商品在同一时刻被很多倍的请求同时来减库存,减库存又分为“拍下减库存”“付款减库存”以及预扣等几种,在大并发更新的过程中都要保证数据的准确性,其难度可想而知。因此,我将用一篇文章来专门讲解如何设计秒杀减库存方案。
虽然我介绍了很多极致的优化思路,但现实中总难免出现一些我们考虑不到的情况,所以要保证系统的高可用和正确性,我们还要设计一个 PlanB 来兜底,以便在最坏情况发生时仍然能够从容应对。专栏的最后,我将带你思考可以从哪些环节来设计兜底方案。

架构原则

架构原则:“4 要 1 不要”

1. 数据要尽量少

为啥“数据要尽量少”呢?

  1. 数据在网络上传输需要时间
  2. 不管是请求数据还是返回数据都需要服务器做处理
  3. 服务器在写网络时通常都要做压缩和字符编码,这些都非常消耗 CPU
    所以减少传输的数据量可以显著减少 CPU 的使用。

例如,我们可以简化秒杀页面的大小,去掉不必要的页面装修效果,等等。
其次,“数据要尽量少”还要求系统依赖的数据能少就少,包括系统完成某些业务逻辑需要读取和保存的数据,这些数据一般是和后台服务以及数据库打交道的。调用其他服务会涉及数据的序列化和反序列化,而这也是 CPU 的一大杀手,同样也会增加延时。而且,数据库本身也容易成为一个瓶颈,所以和数据库打交道越少越好,数据越简单、越小则越好。

2. 请求数要尽量少

用户请求的页面返回后,浏览器渲染这个页面还要包含其他的额外请求,比如说,这个页面依赖的 CSS/JavaScript、图片,以及 Ajax 请求等等都定义为“额外请求”,这些额外请求应该尽量少。因为浏览器每发出一个请求都多少会有一些消耗,例如建立连接要做三次握手,有的时候有页面依赖或者连接数限制,一些请求(例如 JavaScript)还需要串行加载等。另外,如果不同请求的域名不一样的话,还涉及这些域名的 DNS 解析,可能会耗时更久。所以你要记住的是,减少请求数可以显著减少以上这些因素导致的资源消耗。

例如,减少请求数最常用的一个实践就是合并 CSS 和 JavaScript 文件,把多个 JavaScript 文件合并成一个文件,在 URL 中用逗号隔开(??module-preview/index.xtpl.js,module-jhs/index.xtpl.js,module-focus/index.xtpl.js)。这种方式在服务端仍然是单个文件各自存放,只是服务端会有一个组件解析这个 URL,然后动态把这些文件合并起来一起返回。

3. 路径要尽量短(调用链)

所谓“路径”,就是用户发出请求到返回数据这个过程中,需求经过的中间的节点数。

通常,这些节点可以表示为一个系统或者一个新的 Socket 连接(比如代理服务器只是创建一个新的 Socket 连接来转发请求)。每经过一个节点,一般都会产生一个新的 Socket 连接。

所以缩短请求路径不仅可以增加可用性,同样可以有效提升性能(减少中间节点可以减少数据的序列化与反序列化),并减少延时(可以减少网络传输耗时)。

要缩短访问路径有一种办法,就是多个相互强依赖的应用合并部署在一起,把远程过程调用(RPC)变成 JVM 内部之间的方法调用。在《大型网站技术架构演进与性能优化》一书中,我也有一章介绍了这种技术的详细实现。

4. 依赖要尽量少

所谓依赖,指的是要完成一次用户请求必须依赖的系统或者服务,这里的依赖指的是强依赖。

举个例子,比如说你要展示秒杀页面,而这个页面必须强依赖商品信息、用户信息,还有其他如优惠券、成交列表等这些对秒杀不是非要不可的信息(弱依赖),这些弱依赖在紧急情况下就可以去掉。

要减少依赖,我们可以给系统进行分级,比如 0 级系统、1 级系统、2 级系统、3 级系统,0 级系统如果是最重要的系统,那么 0 级系统强依赖的系统也同样是最重要的系统,以此类推。

注意,0 级系统要尽量减少对 1 级系统的强依赖,防止重要的系统被不重要的系统拖垮。例如支付系统是 0 级系统,而优惠券是 1 级系统的话,在极端情况下可以把优惠券给降级,防止支付系统被优惠券这个 1 级系统给拖垮。

5. 不要有单点

系统中的单点可以说是系统架构上的一个大忌,因为单点意味着没有备份,风险不可控,我们设计分布式系统最重要的原则就是“消除单点”。

那如何避免单点呢?我认为关键点是避免将服务的状态和机器绑定,即把服务无状态化,这样服务就可以在机器中随意移动。

把秒杀系统独立出来单独打造一个系统,这样可以有针对性地做优化,例如这个独立出来的系统就减少了店铺装修的功能,减少了页面的复杂度;
在系统部署上也独立做一个机器集群,这样秒杀的大流量就不会影响到正常的商品购买集群的机器负载;
将热点数据(如库存数据)单独放到一个缓存系统中,以提高“读性能”;
增加秒杀答题,防止有秒杀器抢单。

例如秒杀的场景来说,不同QPS量级下瓶颈也会不一样,
10w级别可能瓶颈就在数据读取上,通过增加缓存一般就能解决,
如果要到100w那么,可能服务端的网络可能都是瓶颈,所以要把大部分的静态数据放到cdn上甚至缓存在浏览器里
所以要做架构升级,还是主要要分析在预估的QPS下,整个系统的瓶颈会在什么地方,要针对这起瓶颈来重新设计架构方案

详情、购物车、交易、优惠、库存、物流

References

[0] 开篇词 | 秒杀系统架构设计都有哪些关键点?
[1] 01 | 设计秒杀系统时应该注意的5个架构原则
[2] 02 | 如何才能做好动静分离?有哪些方案可选?
[3] 03 | 二八原则:有针对性地处理好系统的“热点数据”
[4] 04 | 流量削峰这事应该怎么做?
[5] 05 | 影响性能的因素有哪些?又该如何提高系统的性能?
[6] 06 | 秒杀系统“减库存”设计的核心逻辑
[7] 07 | 准备Plan B:如何设计兜底方案?
[8] 08 | 答疑解惑:缓存失效的策略应该怎么定?
[9] 《大型网站技术架构演进》

转自 16 | “order by”是怎么工作的?

16 “order by”是怎么工作的?

select city,name,age from t where city='杭州' order by name limit 1000 ;

全字段排序

以我们前面举例用过的市民表为例,假设你要查询城市是“杭州”的所有人名字,并且按照姓名排序返回前 1000 个人的姓名、年龄。

Extra 这个字段中的“Using filesort”表示的就是需要排序,MySQL 会给每个线程分配一块内存用于排序,称为 sort_buffer。

通常情况下,这个语句执行流程如下所示 :

1.初始化 sort_buffer,确定放入 name、city、age 这三个字段;

2.从索引 city 找到第一个满足 city=’杭州’条件的主键 id,也就是图中的 ID_X;

3.到主键 id 索引取出整行,取 name、city、age 三个字段的值,存入 sort_buffer 中;

4.从索引 city 取下一个记录的主键 id;

5.重复步骤 3、4 直到 city 的值不满足查询条件为止,对应的主键 id 也就是图中的 ID_Y;

6.对 sort_buffer 中的数据按照字段 name 做快速排序;

7.按照排序结果取前 1000 行返回给客户端。

阅读全文 »
0%