不为有趣之事,何遣有涯之生
不失其所者久,死而不亡者寿

Docker简明教程(3)

hzqiuxm阅读(2378)

Docker介绍番外篇,Docker诞生

冷藏厂乱入

谈起Docker,禁不住想起小黑羊小时候在冷藏厂打工的经历.....
为什么冷藏厂会乱入?因为小黑羊说那简直是虚拟化和Docker活生生的例子。

先建个库房

要造冷藏厂,你得先造一个库房对吧?
下面这个库房敞亮不?

能造库房的包工头很多,比如华为、惠普、Dell、联想、曙光、浪潮之类的。
他们给了这些库房一个高大上的名字:物理服务器

库房变成冷藏厂

鱼呀、肉啊就可以存到库房了吗?当然不行!
你需要低温才可以保鲜!不然会发臭坏掉的......

所以我们需要购置制冷机,目前市场上主流的制冷机有两大系列Windows制冷机和Linux制冷机。

配备了制冷机的库房就摇生一变成了冷藏厂了,这样你就可以把你的鸡鸭鱼肉虾、蔬菜、水果都装进来保鲜了

那是不是就皆大欢喜了?NO!NO!NO!相信你也一定注意到了一个问题:各种库藏品都很矫情,放在一起很容易串味儿的,没人喜欢吃咸鱼味的鸡腿或者鸡腿榴莲味的虾吧?而且它们对温度要求也不一致,怎么办?

聪明的泥瓦匠

有个叫VMware的泥瓦匠想了个办法,他把库房隔成很多叫做“虚拟机”的小房间,“密封”起来,每个房间放一个制冷机,这就是冷库虚拟化。
这样就不怕串味儿,每个小房间的温度独立可控,鱼呀虾呀表示很Happy。

世界清净了,后来还有几个泥瓦匠也学会了库房分隔术,到处给人修冷库。
泥瓦匠Vmware用的砌墙工具叫ESXi,泥瓦匠Citrix用的砌墙工具叫Xen Server,泥瓦匠Microsoft用的砌墙工具叫Hyper-V,还有一些草根泥瓦匠用的工具叫KVM

这下总皆大欢喜了吧?然而并没有,这世界上矫情的人太多,如此完美的方案他们还是吹毛求疵瞎BB:

万恶的资本家老板最后问道:还能不能想点别的更好的办法?

Docker横空出世

于是——晴天霹雳一声响,新秀Docker来登场。

制冷机Linux是个喜欢动脑筋的好青年,它发明了一种叫“LXC”的“软隔离”技术,冷库分隔成叫做“容器”的小单间,但每个房间不需要单独安装制冷机,只要布些导冷管和温控阀门,这样看起来就达到目的了。

后来有人把“LXC”这种“软隔离”技术发扬光大,用一堆“GO”零件进行改装,可以大幅提高冷库的建设和改进速度,于是Docker横空出世了。
Docker被业内称为容器管理引擎,其实它就是一套给冷库快速建“单间”和铺“导冷管”的装置,源于LXC,但是更智能。

比如,有些“冷库”的使用者不知道储存“冷冻大虾”的单间该建成什么样,“导冷管”该怎么排布。Docker就建了一个“样板间”展览中心,小白们仿照“样板间”在自家冷库里可以原样造一个出来,这种“样板间”被称为“Docker镜像”,展览中心被称为“Docker Hub”。Docker Hub,你懂滴!


(来自对小黑羊微信公众号文章的整理与改编)

Docker简明教程(2)

hzqiuxm阅读(2332)

Docker概念理解

容器概念理解

容器是一种虚拟化的方案

特点

  • 它是操作系统级别的虚拟化
  • 只能运行相同或相似内核的系统中
  • 依赖linux内核NameSpace和Cgroups(Control Group)特性

相对于虚拟机的优点

  • 虚拟机是利用软件模拟硬件,需要安装操作系统,依赖库,应用;而容器把其中的大头操作系统给去掉了,所以非常轻量化,占用系统资源(硬盘,内存,CPU)会少很多
  • 安装方便,启动速度快

什么是Docker?

  • 将应用程序自动部署到容器的轻量级引擎技术

特点

  • Go语言编写,遵从Apache2.0开源协议
  • 目标是消除各环境差异,实现快速开发测试部署软件生命周期
  • 提倡面向服务的编程,每个容器最好只部署一个微服务

适用场景

  • 适用Docker容器进行开发、测试、部署
  • 创建隔离的环境,很适合个性化的SaaS服务
  • 搭建测试环境

四个核心概念理解

  • Image
    在Docker 中非常非常重要的概念,它是Docker 的核心,Docker 所创建运行的
    Container 完全基于Image 运行,并且它是只读的,我们在下一个册子会去解释,现在您
    只需要记住Image 在Docker 中非常的重要。

  • Repository
    存放Image 的地方,其中Docker Hub 下面就有非常多非常多的Repository,每个
    Repository 有很多很多的Image。

  • Registry
    Registry 其实很容易和Repository 混淆,Docker Hub 在我的理解是一个Registry,
    也就是说Registry 不直接存放Image,Image 是由Registry 下面的若干个Repository 去
    存放的,可能后文中我们会去搭建一个private Registry 存放image,你可以理解我们的
    Registry 下有一个默认的Repository 去存放。

  • Container
    Container 是一个可读写的空间,是由若干个Image 组成的,我们的应用以后都会运
    行在Container 中,同样在后文中我们会为大家介绍如何创建容器,如何启动运行容器。

三层概念

  • Docker Layer 是一个宏观的layer, 包括了若干个read-only 的Images 和一个writable 和readable 的Container layer.
  • Image Layer 是最下面的层(我指的不是Kernel)那些read-only 的Images.
  • Container Layer 是一个可读可写的Layer,我们不仅可以用yum/apt-get 安装软件,而且可以部署我们的服务,产生或者修改一些新的文件.

DockerC/S架构

Docker简明教程(1)

hzqiuxm阅读(2405)

Docker简单安装(CentOS)

依赖检查与源更新

  • Linux内核最好是3.10以上版本
uname -a

  • 更新yum源
yum update

安装方法一:命令安装

  • 输入命令
yum install -y docker-engine

可能遇到的问题

  • 如果提示没有响应的docker包,
    Docker 软件包已经包括在默认的 CentOS-Extras 软件源里,使yum的CentOS-Extras配置生效。
vim /etc/yum.repos.d/CentOS-Base.repo 
将文件CentOS-Base.repo中enabled的値从0变成1
再执行: yum install docker
启动服务:service docker start 或 systemctl start docker

如果无法启动,可能是内核无法支持SELinux,需要修改下配置

vi /etc/sysconfig/docker中配置 //设置为 selinux-enabled = false 再启动就可以了

安装方法二:脚本安装

执行安装脚本

curl -fsSL https://get.docker.com/ | sh

启动服务

service docker start 或者 systemctl start docker

检查安装结果

  • 查看安装信息
docker info

docker version

当然你也可以设置为开机启动:

systemctl enable docker

第一个Hello World

docker run hello-world

用ubuntu系统镜像来打印Hello World

  • 下载ubuntu最近镜像
docker pull ubuntu
  • 查看本地镜像
docker images

  • 创建并运行一个Container的sh环境输出一句话
docker run -t -i docker.io/ubuntu echo "Hello World"

  • 进入你container 中,运行交互式的sh

Nginx安装及SSL相关配置

hzqiuxm阅读(3582)

Nginx安装及SSL相关配置

环境准备

  • GCC编译器安装(编译源码需要使用)
    执行命令gcc -v 查看编译器是否已经安装,如果没有的话安装 执行yum install gcc
    在 linux 编译,需要 gcc,make,cmake,autoconf,libtool 等工具,建议把常用工具都一起安装了
yum -y install gcc make cmake autoconf libtool
  • PCRE库安装(正则表达式库,配置文件需要使用)
    查看是否有pcre包: rpm -qa |grep pcre 一般是系统都有的,
    安装命令 yum -y install pcre pcre-devel 或者:yum install pcre

nginx源码编译安装

  • 下载源码
    前往nginx的官网下载
    获得下载路径后,执行命令 wget http://nginx.org/download/nginx-1.10.3.tar.gz

  • 解压安装包
    执行命令: tar zxvf nginx-1.4.2.tar.gz

  • 编译安装
    进入解压路径cd nginx-1.6.0
    执行命令 ./configure --prefix=/usr/local/nginx 指定安装目录,可以自己决定
    最后执行make && make install

  • 启动或配置
    安装好后,可以在nginx的sbin目录下启动服务,可能出现的错误是默认的80端口被其他程序占用
    使用命令netstat -antp 命令查看
    需要更改nginx配置的话进入conf文件夹下的nginx.conf文件进行配置,详细配置信息请查看nginx配置章节

HTTPS支持

  • 安装OPENSSL(生成证书或秘钥时需要)
    yum -y install openssl-devel

  • 配置编译环境
    执行 ./configure --prefix=/home/java/nginx --with-http_ssl_module
    如要用到其他的模块功能也类似这样安装,下面是比较常用的一些模块
    --with-http_stub_status_module 监控运行状态
    --with-http_ssl_module HTTPS支持
    --with-http_gzip_static_module 静态文件压缩
    --with-http_realip_module 获取真实IP

  • 执行编译安装命令
    make && make install

HTTPS安全配置简单介绍

尽量不要用默认配置,因为版本不同默认配置就会改变
- ssl on 开启SSL
- ssl_certificate 证书,发送给客户端验证服务器身份用,比如www.example.com.crt;nginx只支持一个证书,有中间证书的话要自己合并成一个文件,保证服务器证书在最前面
- ssl_certificate_key 私钥 解密消息,密钥使用 日入:www.example.com.key;
- ssl_protocols 协议 加密握手协议,常见:TLSv1 TLSv1.1 TLSv1.2; 不要配置SSL协议
- ssl_ciphers 加密套件,请选择有前向安全性的加密套件 可以特别指定 如:AES128+EECDH:AES128+EDH ,一般也会指定高安全的并表明禁用的加密套件 HIGH:!aNULL:!MD5(使用高级别的安全套件,禁用MD5);

推荐的加密套件:ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-SHA ECDHE-ECDSA-

AES256-SHAECDHE-ECDSA-AES128-SHA256 ECDHE-ECDSA-AES256-SHA384 ECDHE-RSA-AES128-GCM-SHA256 ...

!aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !MEDIUM

  • ssl_prefer_server_ciphers on; 开启服务器算法优先原则,由服务器来决定适配算法
  • ssl_password_file 将私钥的密码加入到配置文件中(1.7.3版本之后才有,之前都是没有密码的)

    当你有多个站点,使用通配符证书的时候,把证书和私钥放在nginx的http段配置比较好

ssl_certificate     common.crt;
ssl_certificate_key common.key;

server {
    listen          443 ssl;
    server_name     www.example.com;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ...
}

HTTPS配置加强版

DH秘钥交换加强

  • nginx默认提供的DH秘钥交换算法是1024位的,安全性还不够强,可以配置临时的DH秘钥交换
    > 一定要保证客户端也支持哦,比如java8以前是不支持1024位以上的DH参数的
  • 用OpenSSL生成2048位参数文件 openssl dhparam -out dh-2048.pem 2048
  • 配置 ssl_dhparam dh-2048.pem

不推荐更强的DH参数了,因为再高会显著影响SSL的握手效率了

ECDH秘钥交换加强

  • 套件的ECDHE密钥默认是256EC位,使用secp256r1作为曲线模型,加密强度相当于3072位RSA秘钥,应该足够安全了
  • 当然你也可以自己调整 ssl_ecdh_curve secp384r1 相当于7680位RSA密钥
  • 如果是在OpenSSL中使用还是建议用默认的,secp256r1曲线模型在OpenSSL中是做过优化的,运行的更快

HTTPS中TLS会话管理

独立会话缓存配置

  • ssl_session_cache shared:ssl_session_cache:1M 独立会话缓存 例如:shared:SSL:10M;

    分配1M的共享内存缓存,1M大概可以存放4000个会话

  • ssl_session_timeout 会话超时时间 例如:1140m,默认的只有5分钟,建议配置成24小时,能够减少TSL握手时间,提升效率

独立会话票证

  • 默认情况会话票证是由OpenSSL处理的
  • 会话票证使用的是128位的AES加密,web服务器启动初始化时会自动生成一个一次性的,根据服务器配置不同,可能会有多个票证密钥同时使用的情况
  • 服务器重启会生成新的票证密钥,这会导致所有已经接入的客户端需要重新进行TLS会话
  • 出于安全性考虑,每一站点分配一个独立的会话票证是最安全的
    配置 ssl_session_ticket_key ticket.key
  • 当你使用服务器集群且不希望部署共享票证密钥时,可以禁用 ssl_session_tickets off

客户端身份认证

  • 想配置启用客户端身份验证,Nginx需要提供一个完整证书链的所有CA证书,以及一份相关的证书吊销列表
  • 开启客户端验证身份验证配置 ssl_verify_client on;
  • 指定客户端证书到根证书的最大证书路径长度 ssl_verify_depth 2;
  • 指定允许签发客户端证书的CA证书 ssl_client_certificate sub-ca.crt 将发送给用户用于客户端证书选取
  • 完整证书链中需要包含的其他CA证书 ssl_trusted_certificate root-ca.crt
  • 证书吊销列表,文件有更新时Nginx需要重新加载 ssl_revoked-certificates.crl

在Nginx中SSL/TSL协议问题

这个话题其实对Nginx用户来说是个好消息,为什么呢?因为SSL/TSL协议上的问题发现后,在Nginx上都得到了快速的解决,甚至在问题公开之前就修复了

  • 不安全的重新协商

    Nginx直接不支持客户端,也不支持服务器发起重新协商

  • BEAST

    这种攻击需要攻击者控制受害者发送的数据,只有浏览器会受到攻击

  • CRIME

    利用TLS协议启动压缩时信息泄露,Nginx已经对所有OpenSLL版本都支持禁用压缩了

漫谈缓存(1)

hzqiuxm阅读(3059)

1 漫谈缓存 - 缓存概述

前言

在股市动荡,投资乏力时你可能听过现金为王;在传统媒体互联化的潮流中,你可能听过流量为王;在网络知识内容越来越同质的时代,你可能听过内容为王。那么在你系统性能表现不佳,客户抱怨响应时间过长等问题中,我想告诉你的是缓存为王。如果你是个爱吃小龙虾的,那么很多事情没有什么是一顿小龙虾搞不定的,如果搞不定,那就两顿。同理,不管什么系统,位于系统的哪一层,没有什么是缓存解决不了的,如果解决不了那就加一层。

什么是缓存

言归正传,我们来正式谈一谈缓存。我们不要以为经常听到,看到,用到的东西,就一定对其了解。要知道万有引力发现也是从苹果为什么从树上掉下来这么司空见惯的现象中来的。

缓存和缓冲

缓存和缓冲有什么区别?相信很多人其实对这两个词解释不清楚,甚至混用。从英文的角度去看缓存是cache,缓冲是buffer,它们是完全不同的两个单词。

我曾看到有的人是这么解释缓存的:位于速度相差较大的两种硬件/软件之间的,用于协调两者数据传输速度差异的结构。
我觉得这个概念其实更适合缓冲。为什么呢?缓存和缓冲从中文的角度看,仅一字之差,关键性区别就在这一个字。

缓存的侧重点是存,作用是提供一种便利性。比如:我们去超市里买东西,为了增加我们购物的便利性,超市会在购物入口提供一个寄存箱,用来存放我们随身携带的一些大件物品;还有我们经常使用的丰巣快递柜,无论收寄快递,我们只要前往我们住所或上班地点较近的丰巣快递柜进行相应的操作的就行了,丰巣的快递柜为我们寄取物品提供了很好的便利性。
image_1bniasmetrn71nb9fge1endtql1t.png-264.7kB

缓冲的侧重点是冲,它的目的是让对象冲的慢点,作用是提供一种保护性。比如:在公路上,在转弯下坡和小区路口的路段,都会建造一个减速带,用来强行对车子减速,免得车子速度过快产生危险;其实我们平时用的很多东西都有缓冲装置:自行车座位下面的减震垫、一些篮球鞋的鞋垫、运动员跳高竿下面垫子等等物品提供的都是缓冲功能,都是对我们身体部位的保护。

image_1bniar58814ta1si48251vicmvl1g.png-294.4kB

我们再回头看之前的那个解释,大家是不是觉得这个解释更适合缓冲了?所以我更喜欢这么去理解这两个词的概念。

缓存cache:为了提供便利性,建立的数据交换区。
缓冲buffer:为了提供保护性,建立的数据交换区。

计算机缓存

就拿我们熟悉的计算机CPU来举例,看看缓存的作用。

CPU由两大部件组成:控制器和运算器,控制器用来处理指令;运算器用来进行实际运算。

一般我们的数据都会从硬盘上加载到内存中,再由cpu去内存当中去取数据。但是我们看看cpu的频率和内存频率有多大区别。

我们通常衡量一个CPU好坏的指标是其频率,比如4.0GHz,表示一秒钟内这个CPU可以进行4亿次运算,每次运算时间为0.25纳秒。
那么我们去访问内存数据的时间大约是上百纳秒,二者相差百倍。

为了充分利用CPU的高效性,我们引入了多级缓存机制,来增加CPU取数据的便利性。所以一般CPU中会包含一级缓存、二级缓存,甚至有的还有三级缓存。每种缓存的材料都有不同,越是靠近CPU的材料越接近CPU,频率相差越少。

所以通过CPU多级缓存,我们在取数上从二方面增加了便利性,一方面是距离上便利性,本来CPU和内存物理距离上本来就远,而多级缓存更近(类似之前丰巣快递柜);另一方面是时间便利性,由于缓存本身频率更快,取数据的时间更短了。

大多数CPU计算的时候有80-90%的数据是从缓存中直接取得的,使得我们的计算机运行效率大大得到提升。

下图是一个CPU多级缓存的简易示意图:
image_1bnkcol0c1sda1kc7d3ueu91d6e9.png-29.3kB

软件设计Buffer困惑

写过JAVA的人都知道,在JAVA传统的BIO操作里,有很多的流操作,这些输入输出流都是基于抽象基类InputStream/OutputStream。其中有一个缓冲流BufferedxxxStream,相信很多人都用过。但是我碰到过的很多开发人员却把这个流理解成了缓存,因为用了这个流,文件I/O操作的效率比不用之前提升了不少。但是我们可以清楚的看到官方的把它叫做缓冲流,名字也是Buffer打头的。好像也没提供啥保护性,好像你讲的不对哦,这个缓冲提供的明显是便利性,真的是这样吗?

我们想想看,为什么BufferedxxxStream叫缓冲?如果不用它的话,我们是不是要频繁的和硬盘进行I/O操作,有了缓冲流,相当于减少了和I/O的频繁操作次数,就像本来每秒要交互1000次,现在减少到了1次。是不是对硬盘或系统起到了保护性作用?缓冲流正是起到了I/O慢点冲的作用。至于效率上的提升,真是因为次数上的减少,原来的999次对硬盘的操作,变成了对内存的操作。要知道磁盘搜索时间是毫秒级别的,和内存相比,效率相差十万百万倍,所以这才是缓冲流效率提升的真相。

从整体角度看缓存

其实缓存思想在我们计算机或者软件设计上随处可见应用十分广泛。接下来我们看看缓存的分类。

缓存分类

其实目前业界并没有严格的缓存分类,都是根据其实际的应用场景进行分类。

如果按照硬件和软件来分,就可以分成:硬件缓存和软件缓存。

如果按照一个对象类型上可以分为:客户端缓存、服务端缓存、第三方缓存。

如果按照缓存资源类型可以分为:静态缓存和动态缓存。

如果按照缓存的位置可以分为:本地缓存、分布式缓存。

如果按照系统架构上可以分为:web端缓存、应用端缓存、数据库缓存等。

本文不可能穷尽所有的分类方式,也不能面面俱到介绍锁列出的各种缓存类别。作为一个软件开发人员或者架构师,那最常见的方式还是从系统架构作为第一划分维度去了解和掌握缓存,是最直接最有效的。在第一维度的划分下,我们还可以根据第二和第三维度进一步细化。

接下来我们就从系统架构角度来看一看缓存。

系统架构角度看缓存

架构从粗的大方向可以分为三层:WEB层,应用层,持久层。

现代软件设计发展较快,层次也越分越细,但是只是根据功能职责进一步对这三层进行了更细粒度的划分,比如:界面层,控制层,业务层,服务层,代理层,数据层。就是把之前的每层根据功能职责都划分出了二层,就拿原本的应用层来说,划分成了业务层和服务层。业务层可能会对业务的热点数据进行缓存,服务层主要是把一些公共的功能集中起来以SOA或者微服务的方式封装好,以API方式提供,不需要缓存,增大了整个系统的可扩展性。

根据这三层作为第一维度的划分,整理除了下面的表格:
image_1bnkv58kgoq918coo8d1d3o1f5gm.png-30.2kB

缓存对象是指该层主要缓存的是哪些数据,缓存方式是指一般我们会采用什么手段去缓存这些缓存对象,常用技术工具就是各种缓存方式目前比较流行的一些技术与工具了。

缓存的重要指标

我们现在知道,缓存的主要目的是提供便利性。如果你家小区明明有丰巣快递柜,但是要收很高的费用,快递员每次要你到小区门口来拿快递,那这个快递柜(缓存)的意义就没有了。那么软件设计上的缓存也一样,我们要考查这个缓存是不是真的提供了便利性。那怎么衡量呢?我们是通过缓存的命中率来衡量的,说白了就是你去缓存里拿你要的东西能不能拿到。

缓存的问题

这里主要是想和大家说一下,再好的东西,也要我们合理的去利用。一个好的系统缓存需要我们精心去设计,一般的缓存设计会存在这么二个问题:缓存穿透和缓存雪崩。

缓存穿透:是指缓存命中率不高,缓存数据有问题,并没有起到很大的便利性。就像快递员每次收到大物件无法放进快递柜时,会在快递柜给你留了张纸条:请到XXX地领取你的快递。你肯定会说:这又不是寻宝游戏,直接通知我去XXX地不就行了!

缓存雪崩:就是你缓存数据的地方突然奔溃了,这下子本来在缓存处就要返回的请求,必须请求到后端并等待响应了。就像丰巣快递柜自动取件失灵了,每次都要快递员来送取快递了,快递员可能会忙不过来。

至于怎么解决,我们先按下不表,以后会跟大家说清楚,这里主要记得有这么二个概念就行。

小结

本章是对缓存概念的一个整体介绍,让你对缓存有个全方面的了解,你需要掌握的知识点如下:

1 缓存和缓冲的区别是什么?
2 理解计算机CPU多级缓存和缓冲类设计原理
3 从架构角度作为第一维度如何划分缓存类别,每层的缓存对象、缓存方式,常用技术工具有哪些?
4 衡量缓存的重要指标是什么?
5 不好的缓存设计可能会有什么问题?

后面我会对每一层缓存方式和缓存技术工具做详细的介绍,希望本节对你有所帮助。

大型网站架构演变初探

hzqiuxm阅读(2159)

前言

大型网站的发展都是由一个小网站开始的,随着现在越来越多的大型网站出现,导致越来越少的架构师能够去经历一个网站真正从小到大历程。从这点上来说,不对不说是有点遗憾,但是不管是农业社会的发展,还是工业社会的发展,以及当下互联网时代的发展,我们人类教育,科技,文明发展无一不是站在巨人的肩膀上。只有这样才能迅速成长。在这个知识大爆炸的时代,这兴许是已成为自然规律。

虽然现在越来越少有机会去亲身去经历一个小型网站如何逐步进化,蜕变成庞然大物的,但是我们可以参考现有的大型网站,研究它们是如何一步一步走到今天的。不管何种的大型网站架构,一般都会经历从简单到复杂,从单服务器到集群的演变。鄙人不才,作为新手,初探此径。总结了它们一般所经历的几个演变阶段。由于每个行业的业务存在较大差别,所以在某些方面可能会有不同,该演变阶段只是提供了一个简单的演变思路。真正的演变历程,原比我们想象要复杂的多,那是多少前辈与先驱者辛勤劳动与智慧的结晶。

第一阶段:有家网站初长成

由于网站规模很小,所有的程序,文件都会部署在通一台应用服务器上,甚至采用虚拟技术与其它网站共同部署在一台应用服务器上。
那么它的架构大致如下图:

此处输入图片的描述

第二阶段:分而治之

随着网站规模增大,将应用程序,文件存储,数据库单独部署,从而满足更多用户请求
由于每台应用服务器作用不同,它们关注的东西也不尽相同,如应用服务器,我们通常所说的
程序代码都跑在上面,那么最关注的是CPU。

单独部署架构大致如下:

此处输入图片的描述

第三阶段:二八定律

耳熟能详的二八定律再次降临,无论在管理,销售,教育等等领域,都有这经典二八理论一说。那么它对架构有着什么影响呢?

上个阶段我们已经将数据库,文件,应用程序作了单独部署,但是随着用户量的增大,数据库压力将面临挑战。由于大多数用户感兴趣所访问的数据(热门商品,公共数据),一般占了总数据的20%,就像热卖的商品只有性价比高的,或促销的那几样一个道理。那么既然如此我们可以把经常访问的数据事先加载入缓存,这样就不用每次都去访问数据库了。

加入缓存后的架构:

此处输入图片的描述

第四阶段:人多力量大的应用

加了缓存后,数据库的压力是得到了缓解,但是应用还是要被每个用户实实在在访问的,随着用户进一步增大,考虑增加应用服务器,实现集群技术采用负载均衡很好分摊了各服务器的压力。

应用服务器集群化后的架构图:

此处输入图片的描述

第五阶段:速度与主仆

在之前阶段中我们已经对经常访问的数据做了缓存,减轻了数据库的压力。但是缓存的只能是用户需要访问的数据,对于用户需要写入的数据,还是需要实实在在去访问数据库的,所以随着该类型的业务增长,数据库模块必须做出改变。

一般我们会采用读写分离的技术,某几台数据服务器负责写操作,某几台数据服务器负责读操作,负责写的一般称之为主服务器,负责读的则称之为从服务器。然后将主服务器的数据同步到从服务器,从而保证数据的一致性。

一般在这个阶段,说明我们网站的用户规模已经不可小觑了,那么用户体验将变得更加重要。用户体验最直接的影响就是用户通过浏览器来访问你的网页,你让用户看到网页上内容的时间。这个时间不仅仅取决服务的提供者我们,还取决于用户使用的浏览器,用户的使用网络服务商。所以我们必须尽可能让用户第一时间看到他们想要看到的。

一般我们会在负载均衡前再部署2类应用设备,一类叫反向代理服务器,一类叫CDN(内容分发网络,有专门的服务提供商)这二者的本质还是缓存,我们将一些静态元素(html,js,css)和常用的数据缓存在上面,用户发起请求时,部分请求可直接由它们负责响应,大大提升了响应速度。

由于用户有着区域性特点,通过在不同区域增加CDN节点,也能起到提升用户体验的效果。
该阶段的架构图大致如下:

此处输入图片的描述

第六阶段:集群普遍化

随着用户规模越来越大,主从式的数据库也出现了瓶颈,管理的文件也增加了不少,那么我们就将它们也集群化吧。
数据库的集群还可以采用关系数据库与NoSQL数据库混合模式,不仅高效而且灵活。还有可以增加搜索引擎来检索数据。

此处输入图片的描述

第七阶段:SOA与分类

一般到了第六阶段,已经能够应付比较大规模的用户了,但是有的网站,由于其业务繁多,逻辑复杂,或者某些应用在特殊的应用场景下,其压力远远大于其他应用服务器。那么一般我们会采用SOA思想,将不同的应用拆分到不同的应用服务器集群,将相同的应用封装成公共服务,统一管理。不同应用之间还可以采用异步方式,缓解压力,加速响应。

一般到此为止,能够应付绝大多数海量用户了。当然一样的架构,由于其内部模块设计,算法,数据结构等因素,最后的表现也不尽相同。还有不同的企业,由于其业务导向,侧重点不一样,架构上也会做相应的调整。所以没有一成不变的大型网站架构,不变的只有其本质思想。
该阶段的架构图:

此处输入图片的描述

小结

最后对分布式架构部署演变做个简单的小结,罗列了分布式系统演化的各个阶段,根据每个系统自己业务特点,每个阶段的顺序会出现不同,有的甚至会跳过或者几个阶段合并成一个阶段,但其思想脉络还是一脉相承,希望大家通过本文,你对网站系统架构演变有了基本的了解。
- 集所有应用到一台服务器的最简部署
- 分离web服务器和数据库
- 水平增加web服务器
- 加入分布式的文件系统
- 加入缓存服务
- 数据库主从集群、读写分离
- 进一步水平增加web服务器,引入反向代理,负载均衡
- 按业务进行缓存分离,缓存集群
- 数据库分区,分库,分表
- 加入Nosql
- 加入消息系统
- 各种服务均集群化
- 对应用进行拆分部署,甚至是功能级别的细粒度拆分
- 加入F5等硬件设备,CDN服务
- 对重要的节点进行HA集群或者双机热备

常见的负载均衡策略

hzqiuxm阅读(2181)

常见负载均衡策略

前言

随着大规模的集群应用越来越普及,大小企业都会采用负载均衡来实现服务器压力分摊。
本人初步整理了下,目前在企业中常用的几种负载均衡策略。每种策略有着自己的优缺点,适用的场景也不同,所以在一个企业中,
可能存在一种或多种的策略共存情况。

HTTP重定向负载均衡

这个是早期用的比较多的一种负载均衡策略,采用的思路是用一台http服务器来接受用户的请求,通过设置的负责均衡算法,返回一个重定向的真实服务器给用户终端,用户终端根据重定向的URL,访问真实的服务器。该种策略的虽然简单,但是目前可能会被搜索引擎判为SEO作弊,降低搜索排名,需要权衡使用。
http重定向策略架构图:

此处输入图片的描述

DNS域名解析负载均衡

设计思路是利用DNS服务器,对地址解析的时候,直接根据配置好的规则,返回均衡后的IP地址,该策略设计简单省力,性能也有改善,DNS会自动解析离用户最近的一个服务器地址给用户。但是一般DNS解析是一个多级解析,当某台服务器下线后,DNS未及时更新,可能访问已经失效的服务器。所以在实际应用时一般通过DNS返回的是一组服务器,然后再通过其他负载手段访问组服务器中的某台服务器。

DNS域名解析负载策略架构图:
此处输入图片的描述

反向代理负载均衡策略

反向代理服务器是处在服务器前端的位置,一般可以扮演安全,缓存,负载的角色。作为负载服务器,它的有点是简单,缺点是每次都经过反向代理服务器中转,它很容易成为系统瓶颈。

反向代理负载均衡策略架构图:
此处输入图片的描述

IP负载均衡策略

设计思路是采用一台网关服务器,设置上服务器的内外网地址,当用户通过外网地址访问的时候,通过负载算法,将其路由到某台内网服务上。
由于内部服务器和网关采用过的是内网交互,最后网关返回给用户时候,必须将源地址重新修改为网关服务器的外网地址。该策略比起反向代理,性能上有了改善,但是带宽会成为其瓶颈,如果服务的应用以下载功能为主的话,慎用该策略。

IP负载均衡策略架构图:
此处输入图片的描述

数据链路负载均衡策略

IP负载均衡策略采用的是网关服务器修改IP来解决,那么能不能直接让内部服务器返回给用户呢?当然可以,只要负载均衡器修改MAC地址即可,这种方式就被成为数据链路负责均衡策略。这个就避免修改数据包的源地址,目的地址,与目的服务器直接响应。比如LVS采用的就是该种策略。

数据链路负载均衡策略架构图:
此处输入图片的描述

本文中未提及负载均衡算法,在实际应用中,负载均衡策略与负载均衡算法是结合使用的。在某些简单的应用中,可能直接在代码或配置文件中采用均衡算法来实现负载,

程序猿DE密码学(2)

hzqiuxm阅读(3191)

随机数漫谈(下)

故事后续

上回说到,不懂随机数的锁匠,他虽然打造出了世界上最安全的锁,但是所有的锁都是统一的钥匙。只要获得了其中一把钥匙,就可以打开所有的锁了。了解了随机数的三个性质后,锁匠开始准备打造至少具备不可预测性的钥匙来和他的锁配对,这样的组合才是最牢固的。于是他开始了随机数生成器研究。

伪随机数生成器

上一节说到随机数可以用软件方式生成(我们大多数情况下都是这么做的),也可以用硬件方式生成。硬件方式生成才能具备不可重复性,软件无论如何只能生成不可预测性的随机数。我们把这里的硬件设备叫做随机数生成器,而软件则成为伪随机数生成器。因为软件生成的只能做到不可预测性,所以软件生成的随机数,也叫做伪随机数。

伪随机数生成器结构

伪随机数生成器一般由二部分组成:内部状态和外部种子

伪随机数生成器结构

内部状态

伪随机数生成器结构的内部状态,就是指伪随机数生成器管理的内存中的数值(一般是多个)。伪随机数就是根据内存中的值进行一系列的计算,计算的结果就是伪随机数。随后,为了响应下一个伪随机数生成请求,伪随机数会改变自己的内部状态。因此,将根据内部状态计算伪随机数的方法和改变内部状态的方法组合起来,就是伪随机数生成的算法。

内部状态决定了下一个生成的伪随机数,因此内部状态不能被攻击者知道。

种子

为了生成伪随机数,伪随机数生成器需要被称为种子的信息对伪随机数生成器的内部状态进行初始化。

伪随机数的种子是一串随机序列的比特值,然后根据种子结合内部状态,我们就可以生成伪随机数列了。要特别注意:伪随机数生成算法是公开的,但是种子必须保密,这就好像是密码算法是公开的,但密钥必须保密。由于种子是需要保密的,所以不能用容易被预测到的值。例如人们最常犯的错误就是把当前时间作为种子。

打造伪随机数生成器方法

杂乱的方法

有人会说,既然是生成杂乱无章的数列,那么我就使用杂乱无章的方法不就可以了吗?答案当然是否定的,如果你无法理解一个生成方法,那么你如何保证这个复杂的算法生成的数列是具备不可预测性的呢?试验证明,往往这样算法生成的伪随机数周期都非常短。由于密码技术中使用的伪随机数要求具备不可预测性,短周期的数列肯定是不可以的。

线性同余法

线性同余法是一种广泛使用的伪随机数生成器算法。然而,它不能应用于密码技术。

线性同余法算法大概思想就是将当前的伪随机数值乘以A再加上C,然后将除以M得到的余数作为下一个伪随机数
假设我们要生成的伪随机数列伪R0,R1,R2 ......。首先我们根据种子,用下列公式计算第一个伪随机数R0

第一个随机数R0 = (A x 种子 + C)mod M

公式中的A,C都是常数,且A和C需要小于M。接下来,根据R0用相同的公式计算下一个伪随机数R0,如此反复。概括公式如下:

Rn+1 = (A x Rn + C) mod M

在线性同余法中,最近一次生成的伪随机数的值就是内部状态。伪随机数的种子被用来对内部状态进行初始化。它的结构图如下:

线性同余法伪随机数生成器结构图

程序代码示例如下:

public class LineRandom {
    public static void main(String[] args) {

        int m = 7;
        int a = 3;
        int c = 1;
        int random = 0;
        int seed = 1;

        while(true){
            random = (a * seed + c)%m;
            seed = random;
            System.out.print(random);
        }

    }
}

我们看下输出结果:

46520146520146520146520146520146520146520146520146520146520146520146520146520146 ......

可以发现该数列的循环周期是6:465201
在线性同余法中,只要谨慎选择A,C,M的值,就能够很容易地生成具备随机性的伪随机数列。然而,它不具备不可预测性,我们不能将它应用与密码学技术。很多随机数库都是采用线性同余法写的。比如C语言的rand,还有java的Random。所以这些函数不能用于密码技术。

单向散列函数法

使用单向散列函数可以编写出具备不可预测性的伪随机数列(强伪随机数)。它的结构图如下:

单项散列函数法伪随机数生成器

它的工作方式如下:
1 用伪随机数的种子初始化内部状态
2 用单向散列函数计算散列值
3 输出散列值作为强伪随机数
4 修改内部状态
5 根据需要重复2-4步骤

这个工作方式是否可预测呢?攻击者如果想要预测下一个伪随机数,需要知道内部状态的值。而伪随机数是一个散列值,就相当于攻击者要破解散列函数的单向性,这是非常困难的。其实大家都看到了,单向散列函数的单向性是支撑伪随机数生成器不可预测的基础

程序代码示例如下:

public class MacRandom {
    public static final String SHA_ALGORITHM = "SHA-512";

    public static void main(String[] args) throws Exception {

        String counter = "hello world!";//计数器初始值
        String randomStr = "";//随机数


        while (true) {
            randomStr = SHA(counter.getBytes());
            System.out.println(randomStr);
            counter = counter + 1;
        }

    }

    /**
     * SHA Security Hash Algorithm 安全散列算法,固定长度摘要信息 SHA-1 SHA-2( SHA-224
     * SHA-256 SHA-384 SHA-512) 使用的依然是MessageDigest类,JDK不支持224
     *
     * @param plainText
     * @return
     */
    public static String SHA(byte[] plainText) {
        MessageDigest messageDigest;
        try {
            messageDigest = MessageDigest.getInstance(SHA_ALGORITHM);
            return Base64.encodeBase64String(messageDigest.digest(plainText));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

上面代码中我们对内部状态值改变使用了简单的加1操作
篇幅有限这里随机截取了一些输出结果,有兴趣的同学可以自己尝试下,验证其不可预测性

cHRLWs/WLXOLhJ273RhDuN0MBC3plbi0JwyHEUo7gD02J7g8aUK0BYp4JROtTaz88UtgHm8c/9t7
fHGTu9op1Q==

jwW2P0m88M5saQue3Y9hwwVJYVs9JN94EXTkOZfB8Dsw5O9NrciPROFgfcygZ7wvH88ETRpY8ciP
k5pLhjwrAQ==

8X9m7c+1qVctkRljYXbqqZbVTAQ+Y/frL2hmHRamKIaqMO8AMytBD4GyxMPmqbWEVZRm9TLQrRiC
lWOGUa12IQ==

FoNd2JYZlIjbipqB6eShDaE78DGYOV+gw3g++bsaDJPhG88W5VcMLHz9LFDO6ZZr3/iweYChwMNG
aW1iJ5APFw==

RQ9JN8C91v+WoJYsDnlaLPsB0PTe2snp1YLj3yYCWGKknCEcYgnnZEYjEu7TfAEEjHUytWAiyaaR
61BhOzYCjw==

okZDHefqnCLT0qsAZwxA3/R423ccSLtVmlFwlcV3LZOXNdfLULSNz4X0tOKYkO4IfZU49K1UM2it
lEg4OyHw1A==

qRmhTlaQE71wHAo0+XuCBHp2CXA9CwQHYQvb50NTLIRYyEQ/41REx32UZUVqpQVLWtOwyovkUKhC
qPJ8wx5GLg==

HdN5JxdpM+m9XFnLZWois0XsrRE+XSulTfCm0/8ixCPea/DG1HaItbxRqFUnFb2zIw6yJFgeWlV9
QiWdOZmdnQ==

0HKocNlc6Un9c8Pms9vi6ppDrFv9/mq9boY38Ek2DahS4kkpyyjz5OOZD/Hr17DHlMXZKZl1h0QH
1z0rojOOiQ==

znRatSv1+5otr4E98+CPI+MeRqyhH16dbWpsFntxMGAfbTnLK76+mtRUBZ0gge3eXz3l1OB+Qg9y
aJAd9h0o8g==

k9y1PLVypfn1LqNfTCNHvkFJ3EBLYtN4nnXPkVDh+LDBjLobiyswBuoXEexOn1yjjV0fknU9wtUj
1dWKo5RxFA==

密码法

我们可以使用密码来编写能够生成强伪随机数的伪随机数生成器。既可以使用AES对称加密,也可以使用非对称的RSA,ECC算法。
这种伪随机数生成器的结构如下:

密码法伪随机数生成器

它的工作方式如下:
1 用种子的初始值部分初始化内部状态
2 用密钥加密内部状态的值
3 输出密文作为强伪随机数
4 修改内部状态
5 根据需要重复2-4步骤

我们可以看到,密码法的伪随机数生成器中发生最大变化的就是种子,它巧妙的把密钥和初始值作为种子,再结合加密算法,将密文作为伪随机数列。
和单向散列有异曲同工之妙,利用密码法中的密钥的机密性来保证了伪随机数列的不可预测性

由于篇幅原因,就不上示例代码了。先生成密钥后,用密码像单向函数那样进行计算就可以了。该方法的伪程序代码如下:

key 的值与内部状态初始值的结合相当于伪随机数种子

初始值的值相当于内部状态
key = 密码的密钥
counter = 初始值
while(true){
    伪随机数 = 用key加密(counter)
    输出伪随机数
    counter值加1
}

ANSI X9.17

该种方法使用了三重DES算法,它的核心思想和密码法类似。在这里简单介绍下其实现步骤:
1 用种子的初始值部分初始化内部状态
2 将当前时间加密生成掩码
3 对内部状态与掩码求XOR
4 对步骤3的结果用种子密钥部分进行加密
5 将步骤4的结果作为强伪随机数输出
6 对步骤4的结果与掩码求XOR
7 将步骤6的结果用种子密钥部分进行加密
8 将步骤7的结果作为新的内部状态
9 根据需要重复2-8步骤

篇幅原因,这里只给出该程序的伪代码

key 的值与内部状态初始值的结合相当于伪随机数种子

key = 加密密钥
内部状态 = 初始化(内部状态初始值)
while(true){
    掩码 =  用key加密当前时间
    伪随机数 = 用key加密(内部状态 XOR 掩码)
    输出伪随机数
    内部状态 = 用key加密(伪随机数 XOR 掩码)
}

伪随机数生成器常受到的攻击

对种子进行攻击

伪随机数的种子和密钥同等重要。如果攻击者知道了种子,再由于算法是公开的,他就知道这个伪随机数生成器所生成的全部伪随机数列。所以我们必须使用具备了不可重现性的真随机数作为种子。

对随机数池进行攻击

一般我们不会在需要随机数的时候才会去生成,为了生成效率考虑,我们都会事先生成一堆随机数比特序列。我们称之为随机数池,一般保存在文件中。当密码软件需要伪随机数的种子时,我们就从随机池中取出所需长度的随机比特序列来使用。
随机数池本身并不存储任何有意义的信息,但是我们却要认真的保护它们。虽然听上去有点违背常识,但这是你必须要做的。

上期答案: 具备不可重复性。注意审题哦,题目问的是反复掷骰子生成的数列,而不是问掷骰子的点数哦

程序猿DE密码学(1)

hzqiuxm阅读(2824)

随机数漫谈(上)

阅读前希望你具备一定的密码学基础,理解了一些最基本的密码学名词

故事前言

从前有个锁匠,他制锁的手艺非常之高超,他自豪的和村子里的人说:"我制作的锁头十分坚固,小偷绝对打不开。"因此,村子里的人都为自己的房子装上了锁匠打的锁。锁匠的锁,真的非常坚固,没有人能够不用钥匙打开,但是大家发现了一个问题,锁匠做的每把锁的钥匙居然都是相同的!因此小偷只要得到任意一把钥匙就可以打开所有的房子上的锁了!这个粗心的锁匠~

此处输入图片的描述

锁和随机数

从上个故事里我们看到粗心的锁匠做的锁虽然坚固,但是却都用了相同的钥匙,导致一把钥匙可以打开所有的锁了。那么和我今天要讲的随机数有什么关系呢?我们知道在密码学里和安全最机密关系的就是对称密钥或私钥。那么要生成绝对安全性的对称密钥或者私钥,其实都是要用到随机数的,可以说随机数的生成方式就决定了密钥或私钥的安全性。如果我们用了相同的随机数或者不安全的随机数,那么生成的密钥或私钥就如同锁匠打造的锁,其实都用了相同的钥匙,你说随机数重要不重要?

随机数用来做什么?

在密码学里,其实很多地方都用到了随机数,但是我们平时都不太关注它,不知道默默无闻的随机数,在密码学领域时刻在默默无闻的发挥着重要的作用。例如如下场景中,我们就会使用到随机数:

  • 生成密钥

用于对称密码或者消息认证码

  • 生成密钥对

用于公钥密钥(非对称加密)和数字签名,公钥和私钥

  • 生成初始化向量(IV)

用于分组密码的CBC,CFB,OFB模式等

  • 生成nonce

用于防御重放攻击以及分组密码的CTR模式等

  • 生成盐

用于基于口令的密码(PBE)等

这些场景中,随机数扮演的角色都很重要,当然最重要的还是我们之前谈到的这里的头两项:生成密钥和生成密钥对。即使我们的密码算法强度再高,只要攻击者知道了密钥,你加密算法就会立刻形同虚设。而随机数就是让攻击者无法看穿密钥的关键所在。

随机数有哪些性质?

我们今天的随机概念只讲随机数和密码学之间的关系,不会涉及到哲学领域。
我们一般将随机数的性质分为以下三类:
- 随机性:不存在统计学偏差,是完全杂乱的数列(弱伪随机数)
- 不可预测性:不能从过去的数列推测出下一个出现的数(强伪随机数)
- 不可重现性:除非将数列本身保存下来,否则不能重现相同的数列(真伪随机数)

这三个性质的严格程度,是从上到下递增的。下面的性质包含了上面的性质,比如说:具备了不可重现性,就一定具备了不可预测性和随机性。
在密码学领域,至少具备了不可预测性性质的随机数,才可以被用于密码技术。
但是其实,密码学中的随机数也都只是做到了具备不可预测性而已,不会使用到不可重现性性质的随机数。为什么呢?我们接下来简单介绍下每个性质,你就一目了然了。

此处输入图片的描述

随机性

简单的说随机性就是杂乱无章的概念。不可以存在统计学上的偏差(所有值出现的频率相近),比如我们掷骰子,每个点数的出现都是随机的,进行统计的话,1-6的出现概率都是接近1/6的。我们平时玩个游戏,抽个奖,使用的随机数只要具备随机性就可以了。

但是密码学里不可行,因为只是具备随机性的话,不代表不会被看穿,就拿刚才掷骰子的例子,一个筛子只有1-6个点,只要攻击者知道你的随机数使用掷骰子的方式生成的(或者观察了一定次数后),那么就会知道下一次的点数肯定是1-6中的某一个数字,来6个攻击者,每个人猜一个数字,肯定有一个能猜中是吧。

所以,只具备随机性的随机数,我们称之为:弱伪随机数

不可预测性

密码学中的随机数,必须不能被看穿,所以要具备不可预测的性质才行。简单的说不可预测性就是事先不可能说中。复杂点说就是指攻击者在知道过去生成的伪随机数的前提下,依然无法预测出下一个生成出来的伪随机数。

其实伪随机数生成器的算法和密码学中加密算法一样,都是公开的。但是伪随机数生成器的种子(你可以理解成生成随机数需要的密钥)是保密的。所以即使攻击这知道了之前所有的伪随机数以及生成算法,他也无法预测出下一个生成出来的伪随机数,这就是不可预测性。

那么如何编写出不可预测性的伪随机数生成器呢?这是个很有趣的问题,我们的不可预测性其实是通过其他密码技术来实现的。例如:可以通过单向散列函数的单向性和密码的机密性来保证伪随机数生成器的不可预测性。后面会有详细的代码示例。

我们把具备不可预测性的随机数称之为:强伪随机数

不可重现性

不可重现性就是指无法重现和某一种随机数列完全相同的数列的性质。如果除了将随机数列本身保存下来以外,没有其他方法重现该数列。

告诉大家一个不幸的消息:使用软件是无法生成出具备不可重复性的随机数列的。软件只能生成伪随机数列,所以软件实现的随机数生成器,我们就称作伪随机数生成器。那这是什么原因呢?那是因为运行软件的计算机本身仅具备有限的状态集,在内部状态相同的情况下,软件必然会生成相同的数,所以通过软件生成的随机数,一定会重复。重复的长度我们称之为周期。周期可以很短,也可以很长,但终归还是有限的。

要生成具备不可重复性的随机数列,需要从不可重现的物理现象中获取信息。比如周围的温度和声音变化,鼠标的移动位置信息,键盘输入的时间间隔,放射线测量仪输出值等。根据硬件中获取到的信息生成的数列,一般可以认为是具备不可重复性的随机数列。

目前,已经出现了用传感器感知热度变化,并根据这一变化的信息来生成具备不可重复性的随机数列的硬件设备。但是要让这样的设备成为计算机的标配,那还需要比较长的一段时间。

我们把具备不可重复性的随机数称之为:真随机数

本文的漫谈就先到这里,下篇中我会给大家介绍伪随机数生成器的设计方法以及简单代码示例,还有一些常见的攻击方式。
最后问大家一个问题:我们反复掷骰子所生成的数列,是否具备不可重复性呢?答案见《随机数漫谈(下)》末尾

SpringCloud微服务系列(1)

hzqiuxm阅读(4835)

微服务与SpringCloud入门

微服务的实现方式

  • 1 Doubbo
  • 2 SpringCloud
  • 3 其他开源实现

参考链接

Spring Cloud:http://projects.spring.io/spring-cloud
Dubbo:http://dubbo.io
Dropwizard:http://www.dropwizard.io
Consl、etcd &etc.

SpringCloud中的概念名字一览

Eureka Server


- 依赖于:spring-cloud-starter-eureka-server (默认是服务端和客户端为一体的)
- 作为服务使用时,一般需要关闭掉客户端的功能
- 注册中心,可以注册服务的提供者,服务的调用者,服务网关,服务跟踪者,配置服务等
- 当需要多个注册中心时,可以配置和其他注册中心同步,实现高可用

Eureka Client


- 依赖于:spring-cloud-starter-eureka-server
- 任何需要注册到注册中心的服务,都是Eureka Clinet,可以是服务提供者,调用者,服务网关,服务跟踪者,配置服务等

Ribbon


- 客户端的负载均衡器
- ribbon是一个负载均衡客户端,可以很好的控制http和tcp的一些行为
- 依赖于:spring-cloud-starter-eureka-server,spring-cloud-starter-ribbon
- 结合restTemplate使用,通过@ LoadBalanced注册表明,这个restTemplate是负载均衡的
- 支持简单的URL访问,复杂的不太适合
- 可以单独使用,不依赖于Eureka

Hystrix

  • 断路器,防止微服务出现雪崩现象
  • 依赖于:spring-cloud-starter-hystrix
  • 有的SpringCloud版本默认已经为Feign整合了Hystrix(亲自测试Edgware是没有自动支持的,需要添加依赖并在配置文件中开启),我们要做的是自定义添加回退函数和原因

Feign


- 它是一个声明式的http客户端负载功能,其实也是依赖Ribbon
- 使用的时候坑还是有点多的,要多注意
- 通过注解方式,弥补了Ribbon访问时只适合URL的方式
- 依赖于:spring-cloud-starter-eureka-server,spring-cloud-starter-feign(包含了Ribbon,Hystrix)
- Feign有自己的注解,但是spring为了降低大家的使用成本,对其做了一些封装改造,很多的地方可以使用spring的注解来操作
- 使用注解@FeignClient(value = "服务名")来指定哪个服务

Zuul


- 网关中心,外部客户端统一调用网关,由网关协调各服务调用
- 依赖于:spring-cloud-starter-zuul
- 网关中心好处:易于监控,易于认证,减少客户端与各个微服务之间的交互次数

SpringCloudConfig


- 分布式配置中心,分为服务端server和客户端client
- 依赖于:spring-cloud-config-server,spring-cloud-starter-eureka-server
- config-client从config-server获取了foo的属性
- config-server从git仓库中获取配置,仓库可以是本地也可以是远程

  • http请求地址和资源文件映射如下:
    /{application}/{profile}[/{label}]
    /{application}-{profile}.yml
    /{label}/{application}-{profile}.yml
    /{application}-{profile}.properties
    /{label}/{application}-{profile}.properties

Spring Cloud Bus

  • 消息总线

Sleuth

  • 追踪器,为spring cloud 提供了分布式跟踪的解决方案
  • 依赖于: spring-cloud-starter-sleuth
  • 一般还会同其他的日志系统结合使用:ELK

SpringCloud整体图

欢迎加入极客江湖

进入江湖关于作者