HTTP长连接和短连接介绍

being 发表了文章 • 0 个评论 • 152 次浏览 • 2017-05-06 13:29 • 来自相关话题

1、HTTP协议与TCP/IP协议的关系​
HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。
 
2、如何理解HTTP协议是无状态的
HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。
 
3、什么是长连接、短连接?
在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。
 
但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
 
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
 
3.1 TCP连接
当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接 时它们可以释放这个连接,连接的建立是需要三次握手的,而释放则需要4次握手,所以说每个连接的建立都是需要资源消耗和时间消耗的

经典的三次握手示意图:








经典的四次挥手关闭图:
 








 
3.2 TCP短连接
我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server 发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起 close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在 client/server间传递一次读写操作

短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段
 
3.3 TCP长连接
接下来我们再模拟一下长连接的情况,client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务 器端检测到这种半开放的连接。

如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一:
客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。
 
长连接短连接操作过程:
短连接的操作步骤是:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接

长连接的操作步骤是:建立连接——数据传输...(保持连接)...数据传输——关闭连接
 
4、 长连接和短连接的优点和缺点
由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。

短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。

长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。
 
5、什么时候用长连接,短连接? 
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。 
  
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。 查看全部
1、HTTP协议与TCP/IP协议的关系​
HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。
 
2、如何理解HTTP协议是无状态的
HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。
 
3、什么是长连接、短连接?
HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。
 
但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:
Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
 
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
 
3.1 TCP连接
当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接 时它们可以释放这个连接,连接的建立是需要三次握手的,而释放则需要4次握手,所以说每个连接的建立都是需要资源消耗和时间消耗的

经典的三次握手示意图:
tcp.png

san.png

经典的四次挥手关闭图:
 
huishou.png

si.png

 
3.2 TCP短连接
我们模拟一下TCP短连接的情况,client向server发起连接请求,server接到请求,然后双方建立连接。client向server 发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起 close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在 client/server间传递一次读写操作

短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段
 
3.3 TCP长连接
接下来我们再模拟一下长连接的情况,client向server发起连接,server接受client连接,双方建立连接。Client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。

首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务 器端检测到这种半开放的连接。

如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一:
  1. 客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。
  2. 客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
  3. 客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
  4. 客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。

 
长连接短连接操作过程:
短连接的操作步骤是:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接

长连接的操作步骤是:建立连接——数据传输...(保持连接)...数据传输——关闭连接
 
4、 长连接和短连接的优点和缺点
由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,Client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可 以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。

短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。

长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。
 
5、什么时候用长连接,短连接? 
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。 
  
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。

甲骨文发布云端仓库管理系统软件V8

OT学习平台 发表了文章 • 0 个评论 • 128 次浏览 • 2017-05-02 14:27 • 来自相关话题

OTPUB直播活动又双叒叕来喽!

直播主题

Salesforce爱因斯坦Einstein人工智能解决方案

直播时间

2017年5月11日 14:00-15:00
点击报名>>>
 甲骨文近日发布了新版本的仓库管理系统(WMS)软件,甲骨文表示可以帮助企业处理全渠道实现问题的挑战。
据悉,Oracle仓库管理云产品版本8中的增强功能,有助于提升从供应商到配送中心(DC)到商店货架库存的完整库存管理。
甲骨文在2016年收购了LogFire,与Manhattan Associates和JDA Software Group等专注在物流管理的企业展开竞争。通过收购LogFire,Oracle通过仓库管理系统进一步提升其在ERP市场的地位,从而扩全渠道供应链市场的能力。
据调查显示,物流软件市场将从从2015年的12亿美元增长到2024年的41亿美元。甲骨文表示,将通过继续投资物流软件,不断提升其在云端WMS市场的份额。
甲骨文指出,最新版本使用100%的基于云的架构,以及提供与Oracle供应链管理(SCM)云中的其他软件产品的连接。
甲骨文的CSM产品战略集团副总裁Jon Chorley表示:“LogFire已经证明了其基于云的WMS的可行性,Oracle WMS Cloud是满足用户全生命周期的解决方案,它可以让企业在当今动态互联的全方位实体经济获得价值。” 查看全部
OTPUB直播活动又双叒叕来喽!

直播主题

Salesforce爱因斯坦Einstein人工智能解决方案

直播时间

2017年5月11日 14:00-15:00
点击报名>>>
 甲骨文近日发布了新版本的仓库管理系统(WMS)软件,甲骨文表示可以帮助企业处理全渠道实现问题的挑战。
据悉,Oracle仓库管理云产品版本8中的增强功能,有助于提升从供应商到配送中心(DC)到商店货架库存的完整库存管理。
甲骨文在2016年收购了LogFire,与Manhattan Associates和JDA Software Group等专注在物流管理的企业展开竞争。通过收购LogFire,Oracle通过仓库管理系统进一步提升其在ERP市场的地位,从而扩全渠道供应链市场的能力。
据调查显示,物流软件市场将从从2015年的12亿美元增长到2024年的41亿美元。甲骨文表示,将通过继续投资物流软件,不断提升其在云端WMS市场的份额。
甲骨文指出,最新版本使用100%的基于云的架构,以及提供与Oracle供应链管理(SCM)云中的其他软件产品的连接。
甲骨文的CSM产品战略集团副总裁Jon Chorley表示:“LogFire已经证明了其基于云的WMS的可行性,Oracle WMS Cloud是满足用户全生命周期的解决方案,它可以让企业在当今动态互联的全方位实体经济获得价值。”

Python操作各种数据库

采菊篱下 发表了文章 • 0 个评论 • 165 次浏览 • 2017-04-27 17:54 • 来自相关话题

我们在写代码的时候,经常会操作数据库,增删改查,数据库有很多类型,关系型数据库和非关系数据库,这里咱们介绍一下python怎么操作mysql、redis和mongodb。
 

一、操作mysql

python3中操作mysql数据需要安装一个第三方模块,pymysql,使用pip install pymysql安装即可,在python2中是MySQLdb模块,在python3中没有MySQLdb模块了,所以使用pymysql。
import pymysql
# 创建连接,指定数据库的ip地址,账号、密码、端口号、要操作的数据库、字符集
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='data',charset='utf8')
# 创建游标
cursor = conn.cursor()
# 执行SQL,并返回收影响行数
effect_row = cursor.execute("update students set name = 'niuhy' where id = 1;")
# 执行SQL,并返回受影响行数
#effect_row = cursor.execute("update students set name = 'niuhy' where id = %s;", (1,))
# 执行SQL,并返回受影响行数
effect_row = cursor.executemany("insert into students (name,age) values (%s,%s); ", [("hangyang",18),("12345",20)])
#执行select语句
cursor.execute("select * from students;")
#获取查询结果的第一条数据,返回的是一个元组
row_1 = cursor.fetchone()
# 获取前n行数据
row_2 = cursor.fetchmany(3)
# 获取所有数据
row_3 = cursor.fetchall()
# 提交,不然无法保存新建或者修改的数据
conn.commit()
# 获取最新自增ID
new_id = cursor.lastrowid
print(new_id)
# 关闭游标
cursor.close()
# 关闭连接
conn.close()上面的操作,获取到的返回结果都是元组,如果想获取到的结果是一个字典类型的话,可以使用下面这样的操作
import pymysql
# 创建连接,指定数据库的ip地址,账号、密码、端口号、要操作的数据库、字符集
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='data',charset='utf8')
# 创建游标
cursor = conn.cursor()

cursor = coon.cursor(cursor=pymysql.cursors.DictCursor)#需要指定游标的类型,字典类型
# 执行SQL
cursor.execute("select * from user;")
#获取返回结果,这个时候返回结果是一个字典
res = cursor.fetchone()#返回一条数据,如果结果是多条的话
print(res)
res2 = cursor.fetchall()#所有的数据一起返回

二、操作redis

redis是一个nosql类型的数据库,数据都存在内存中,有很快的读写速度,python操作redis使用redis模块,pip安装即可
import redis
r = redis.Redis(host='127.0.0.1',port=6379,db=0)#指定连接redis的端口和ip以及哪个数据库
r.set('name', 'value')#set string类型的值
r.setnx('name2', 'value')#设置的name的值,如果name不存在的时候才会设置
r.setex('name3', 'value', 3)#设置的name的值,和超时时间,过了时间key就会自动失效
r.mset(k1='v1',k2='v2')#批量设置值
r.get('name')#获取值
print(r.mget('k1','k2'))#批量获取key

r.delete('name')#删除值
r.delete('k1','k2')#批量删除
#======下面是操作哈希类型的
r.hset('hname', 'key', 'value')#set 哈希类型的值
r.hset('hname', 'key1', 'value2')#set 哈希类型的值
r.hsetnx('hname','key2','value23')#给name为hname设置key和value,和上面的不同的是key不存在的时候
#才会set
r.hmset('hname',{'k1':'v1','k2':'v2'})#批量设置哈希类型的key和value
r.hget('name', 'key')#获取哈希类型的值
print(r.hgetall('hname'))#获取这个name里所有的key和value
r.hdel('hname','key')#删除哈希类型的name里面指定的值
print(r.keys())#获取所有的key

三、操作mongodb

mongodb和redis一样,也是一个nosql类型的数据库,它和redis的区别是,redis把整个数据都放在内存,而mongodb是把数据放在磁盘上的。 python操作mongodb使用pymongo模块,pip安装即可,操作如下:
import pymongo
conn = pymongo.MongoClient(host='211.149.218.16',port=27017)#连接mongodb
db = conn.szz#选择哪个数据库
db.authenticate('admin','123456')#如果有账号密码的话,指定账号密码
collection = db.stus#使用数据库里面哪个集合,就相当于mysql里面的表
collection.drop()#删除指定的集合,也就是删除这个表
stu={
'name':'牛牛',
'age':38,
'sex':'男'
}
stus = [
{'name':'python',
'addr':'北京',
'sex':'未知',
'age':38
},
{
'name':'mongodb',
'addr':'USA',
'money':18.01,
'age':20
}
]
collection.save(stu)#插入单条数据
collection.insert(stus)#插入单条和多条,如果是多条的话,传入的就是一个list
=====比较操作符=======
# $lt
# 小于
# $lte
# 小于等于
# $gt
# 大于
# $gte
# 大于等于
# $ne
# 不等于
$set 获取前面的结果集
collection.update({'name':'牛牛'},{'name':'niuhy','age':20})#更新数据
collection.update({'name':'牛牛'},{'$set':{'addr':'河南'}})#在原来数据的基础上修改
collection.update({'name':'牛牛'},
{'$set':{'addr':'河南'}},
multi=True)#multi参数的作用是如果有多个结果的话,是否全部修改

collection.remove({'name':'牛牛'})#删除指定的数据,如果不传入参数,删除的是全部的数据
collection.remove()#删除全部数据
data = collection.find({'name':'mongodb'})#查询指定的数据
all_data = collection.find()#不写参数就是查询所有的数据
my_data = collection.find({'age':{'$gte':18}})#查询大于18岁的
for d in my_data:#获取数据,所有查询数据都需要使用循环来获取
print(d)#每个元素都是一个字典分享转载原文:牛牛杂货铺。 查看全部
我们在写代码的时候,经常会操作数据库,增删改查,数据库有很多类型,关系型数据库和非关系数据库,这里咱们介绍一下python怎么操作mysql、redis和mongodb。
 


、操作mysql


python3中操作mysql数据需要安装一个第三方模块,pymysql,使用pip install pymysql安装即可,在python2中是MySQLdb模块,在python3中没有MySQLdb模块了,所以使用pymysql。
import pymysql
# 创建连接,指定数据库的ip地址,账号、密码、端口号、要操作的数据库、字符集
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='data',charset='utf8')
# 创建游标
cursor = conn.cursor()
# 执行SQL,并返回收影响行数
effect_row = cursor.execute("update students set name = 'niuhy' where id = 1;")
# 执行SQL,并返回受影响行数
#effect_row = cursor.execute("update students set name = 'niuhy' where id = %s;", (1,))
# 执行SQL,并返回受影响行数
effect_row = cursor.executemany("insert into students (name,age) values (%s,%s); ", [("hangyang",18),("12345",20)])
#执行select语句
cursor.execute("select * from students;")
#获取查询结果的第一条数据,返回的是一个元组
row_1 = cursor.fetchone()
# 获取前n行数据
row_2 = cursor.fetchmany(3)
# 获取所有数据
row_3 = cursor.fetchall()
# 提交,不然无法保存新建或者修改的数据
conn.commit()
# 获取最新自增ID
new_id = cursor.lastrowid
print(new_id)
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
上面的操作,获取到的返回结果都是元组,如果想获取到的结果是一个字典类型的话,可以使用下面这样的操作
import pymysql
# 创建连接,指定数据库的ip地址,账号、密码、端口号、要操作的数据库、字符集
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='data',charset='utf8')
# 创建游标
cursor = conn.cursor()

cursor = coon.cursor(cursor=pymysql.cursors.DictCursor)#需要指定游标的类型,字典类型
# 执行SQL
cursor.execute("select * from user;")
#获取返回结果,这个时候返回结果是一个字典
res = cursor.fetchone()#返回一条数据,如果结果是多条的话
print(res)
res2 = cursor.fetchall()#所有的数据一起返回


、操作redis


redis是一个nosql类型的数据库,数据都存在内存中,有很快的读写速度,python操作redis使用redis模块,pip安装即可
import redis
r = redis.Redis(host='127.0.0.1',port=6379,db=0)#指定连接redis的端口和ip以及哪个数据库
r.set('name', 'value')#set string类型的值
r.setnx('name2', 'value')#设置的name的值,如果name不存在的时候才会设置
r.setex('name3', 'value', 3)#设置的name的值,和超时时间,过了时间key就会自动失效
r.mset(k1='v1',k2='v2')#批量设置值
r.get('name')#获取值
print(r.mget('k1','k2'))#批量获取key

r.delete('name')#删除值
r.delete('k1','k2')#批量删除
#======下面是操作哈希类型的
r.hset('hname', 'key', 'value')#set 哈希类型的值
r.hset('hname', 'key1', 'value2')#set 哈希类型的值
r.hsetnx('hname','key2','value23')#给name为hname设置key和value,和上面的不同的是key不存在的时候
#才会set
r.hmset('hname',{'k1':'v1','k2':'v2'})#批量设置哈希类型的key和value
r.hget('name', 'key')#获取哈希类型的值
print(r.hgetall('hname'))#获取这个name里所有的key和value
r.hdel('hname','key')#删除哈希类型的name里面指定的值
print(r.keys())#获取所有的key


、操作mongodb


mongodb和redis一样,也是一个nosql类型的数据库,它和redis的区别是,redis把整个数据都放在内存,而mongodb是把数据放在磁盘上的。 python操作mongodb使用pymongo模块,pip安装即可,操作如下:
import pymongo
conn = pymongo.MongoClient(host='211.149.218.16',port=27017)#连接mongodb
db = conn.szz#选择哪个数据库
db.authenticate('admin','123456')#如果有账号密码的话,指定账号密码
collection = db.stus#使用数据库里面哪个集合,就相当于mysql里面的表
collection.drop()#删除指定的集合,也就是删除这个表
stu={
'name':'牛牛',
'age':38,
'sex':'男'
}
stus = [
{'name':'python',
'addr':'北京',
'sex':'未知',
'age':38
},
{
'name':'mongodb',
'addr':'USA',
'money':18.01,
'age':20
}
]
collection.save(stu)#插入单条数据
collection.insert(stus)#插入单条和多条,如果是多条的话,传入的就是一个list
=====比较操作符=======
# $lt
# 小于
# $lte
# 小于等于
# $gt
# 大于
# $gte
# 大于等于
# $ne
# 不等于
$set 获取前面的结果集
collection.update({'name':'牛牛'},{'name':'niuhy','age':20})#更新数据
collection.update({'name':'牛牛'},{'$set':{'addr':'河南'}})#在原来数据的基础上修改
collection.update({'name':'牛牛'},
{'$set':{'addr':'河南'}},
multi=True)#multi参数的作用是如果有多个结果的话,是否全部修改

collection.remove({'name':'牛牛'})#删除指定的数据,如果不传入参数,删除的是全部的数据
collection.remove()#删除全部数据
data = collection.find({'name':'mongodb'})#查询指定的数据
all_data = collection.find()#不写参数就是查询所有的数据
my_data = collection.find({'age':{'$gte':18}})#查询大于18岁的
for d in my_data:#获取数据,所有查询数据都需要使用循环来获取
print(d)#每个元素都是一个字典
分享转载原文:牛牛杂货铺

企业级管理及项目管理软件的发展趋势

OT学习平台 发表了文章 • 0 个评论 • 159 次浏览 • 2017-04-24 15:35 • 来自相关话题

OTPUB直播活动又双叒叕来喽!

直播主题

Excel的“天上人间”-“出台”到PPT的动态图表

直播时间

2017年4月25日 14:00-15:00
点击报名观看>>>


发展才是硬道理,企业中的各种制度目的终为了企业发展。在过去,我们总是在强调制度,由于企业是一个复杂的系统,企业的管理制度也必然是一个复杂的系统。任何一个制度的实施,都有可能由于相关方面制度的不完善或缺失而造成负面的影响。因此管理制度本身应该是完善的,涵盖企业管理系统的方方面面,并且随着企业内外环境的变化,不断地加以补充、修订和加强。
企业级管理及项目管理软件的发展趋势
经过数年的发展建设,企业信息化从部门级初步应用如办公、财务、人力等进入流程为中心的一体化管理模式,为提升企业管理效率的企业级。移动互联网、云计算发展迅速,企业管理在技术上也推行革新。很多企业借助科技发展带来的便利,随着大数据、商业智能、云计算这些技术而来,企业管理软件发展是这样的…
1、 一体化管理模式。企业管理系统是新的工作管理方式。互联网企业对软件、硬件、数据、计算等资源需求强烈。智能化的管理提供更多机会,相比传统的企业管理方案,一体化管理带来更完整的架构。
2、移动办公成主流。智能手机推动移动办公,手机、平板灯设备记录工作、管理工作流程越来越常见,经常外出的工作人员就可以方便使用。
3、个性化的管理定制。随着市场的发展变化,企业对管理方式的智能和个性化需求也凸显出来。根据不同的管理要求,可以通过自主灵活的定制功能来解决难题。
智能化企业管理服务的发展,让企业能够具备更快速的反应能力、打造更简洁的业务流程,强化了企业应对复杂环境的核心竞争力。而一体化管理模式将促进企业管理生态的形成和发展,通过一个系统能够快速调动各资源彼此配合,形成网状的交互生态圈,信息的实时共享大大提升了数据的安全性和可控度,为企业的信息化提供强有力的支撑。
关于项目管理软件
如今,项目管理备受重视,原因是项目管理在运筹与协同方面的方式方法恰好填充了其它管理体系或管理系统这方面的相对弱项;PMI的PMBOK或IPMA的ICB等关于项目管理的理论体系日臻完善,并在全球范围内展开几近商业性质的普及推广;项目管理软件软件功能及演绎理论能力的不断提高,使项目管理从理论走向实际实施进而发挥效益成为现实;引导企业管理风向标的跨国公司纷纷开始在企业中采用项目管理技术和项目管理解决方案,初步形成了企业项目管理化的局面。
随着越来越多的企业或组织对项目管理方法和技术的引入,以及大家对项目管理理解的深入,因此未来的项目管理软件市场的发展是机遇和挑战同时并存的。 用户的需求对于未来的企业级项目管理软件所采用技术也提出了更高的要求,如大数据量存储、大用户量并发访问、企业多分支机构的支持、大用户量的系统维护、系统的可扩展性/可集成性/可定制性等等。
由于国内项目管理软件开发起步较晚,涉足开发企业级项目管理软件的企业也微乎其微,目前国内企业级项目管理软件高端市场几乎由国外厂商垄断。
未来,企业级项目管理软件发展将会:1、通用型项目管理解决方案;2、IT项目管理解决方案;3、大核心功能实现度解决方案…,如今市场前景比较广阔,产品的先进性是重要的,但是满足不同层次客户的需求也是及其重要的。伴随着项目管理在中国的迅猛发展,客户对项目管理的理性认识,以及项目管理软件厂商对项目管理先进理念和方法的倡导,谁会是最后的赢家?是厂商、是客户、还是专业的咨询/服务公司?请拭目以待... 查看全部
OTPUB直播活动又双叒叕来喽!

直播主题

Excel的“天上人间”-“出台”到PPT的动态图表

直播时间

2017年4月25日 14:00-15:00
点击报名观看>>>


发展才是硬道理,企业中的各种制度目的终为了企业发展。在过去,我们总是在强调制度,由于企业是一个复杂的系统,企业的管理制度也必然是一个复杂的系统。任何一个制度的实施,都有可能由于相关方面制度的不完善或缺失而造成负面的影响。因此管理制度本身应该是完善的,涵盖企业管理系统的方方面面,并且随着企业内外环境的变化,不断地加以补充、修订和加强。
企业级管理及项目管理软件的发展趋势
经过数年的发展建设,企业信息化从部门级初步应用如办公、财务、人力等进入流程为中心的一体化管理模式,为提升企业管理效率的企业级。移动互联网、云计算发展迅速,企业管理在技术上也推行革新。很多企业借助科技发展带来的便利,随着大数据、商业智能、云计算这些技术而来,企业管理软件发展是这样的…
1、 一体化管理模式。企业管理系统是新的工作管理方式。互联网企业对软件、硬件、数据、计算等资源需求强烈。智能化的管理提供更多机会,相比传统的企业管理方案,一体化管理带来更完整的架构。
2、移动办公成主流。智能手机推动移动办公,手机、平板灯设备记录工作、管理工作流程越来越常见,经常外出的工作人员就可以方便使用。
3、个性化的管理定制。随着市场的发展变化,企业对管理方式的智能和个性化需求也凸显出来。根据不同的管理要求,可以通过自主灵活的定制功能来解决难题。
智能化企业管理服务的发展,让企业能够具备更快速的反应能力、打造更简洁的业务流程,强化了企业应对复杂环境的核心竞争力。而一体化管理模式将促进企业管理生态的形成和发展,通过一个系统能够快速调动各资源彼此配合,形成网状的交互生态圈,信息的实时共享大大提升了数据的安全性和可控度,为企业的信息化提供强有力的支撑。
关于项目管理软件
如今,项目管理备受重视,原因是项目管理在运筹与协同方面的方式方法恰好填充了其它管理体系或管理系统这方面的相对弱项;PMI的PMBOK或IPMA的ICB等关于项目管理的理论体系日臻完善,并在全球范围内展开几近商业性质的普及推广;项目管理软件软件功能及演绎理论能力的不断提高,使项目管理从理论走向实际实施进而发挥效益成为现实;引导企业管理风向标的跨国公司纷纷开始在企业中采用项目管理技术和项目管理解决方案,初步形成了企业项目管理化的局面。
随着越来越多的企业或组织对项目管理方法和技术的引入,以及大家对项目管理理解的深入,因此未来的项目管理软件市场的发展是机遇和挑战同时并存的。 用户的需求对于未来的企业级项目管理软件所采用技术也提出了更高的要求,如大数据量存储、大用户量并发访问、企业多分支机构的支持、大用户量的系统维护、系统的可扩展性/可集成性/可定制性等等。
由于国内项目管理软件开发起步较晚,涉足开发企业级项目管理软件的企业也微乎其微,目前国内企业级项目管理软件高端市场几乎由国外厂商垄断。
未来,企业级项目管理软件发展将会:1、通用型项目管理解决方案;2、IT项目管理解决方案;3、大核心功能实现度解决方案…,如今市场前景比较广阔,产品的先进性是重要的,但是满足不同层次客户的需求也是及其重要的。伴随着项目管理在中国的迅猛发展,客户对项目管理的理性认识,以及项目管理软件厂商对项目管理先进理念和方法的倡导,谁会是最后的赢家?是厂商、是客户、还是专业的咨询/服务公司?请拭目以待...

Centos下安装NFS服务

Ansible 发表了文章 • 0 个评论 • 182 次浏览 • 2017-04-22 20:10 • 来自相关话题

如果生产环境,可以利用heartbeta或者keepalived作高可用,下面介绍一下nfs服务安装过程。
 

一、安装环境

NFS服务器:CentOS6.5 192.168.0.10
NFS客户端:CentOS6.5 192.168.0.11
 

二、服务器端安装配置​

1、先用rpm -qa命令查看所需安装包(nfs-utils、rpcbind)是否已经安装:
[root@local /]# rpm -qa | grep "rpcbind"
rpcbind-0.2.0-11.el6.x86_64
[root@local /]# rpm -qa | grep "nfs"
nfs-utils-1.2.3-39.el6.x86_64
nfs4-acl-tools-0.3.3-6.el6.x86_64
nfs-utils-lib-1.1.5-6.el6.x86_642、如查询结果如上,说明服务器自身已经安装了NFS,如果没有安装,则用yum命令来安装:
[root@local /]# yum -y install nfs-utils rpcbind3、创建共享目录:
[root@local /]# mkdir /sharestore4、NFS共享文件路径配置:
编辑/etc/exports添加下面一行,添加后保存退出。
 
[root@local /]# vi /etc/exports
/sharestore *(rw,sync,no_root_squash)/sharestore 10.10.0.0/8(rw,sync,no_subtree_check,anonuid=48,anongid=48)你也可以指定可以访问网段和用户id。
 
5、启动NFS服务(先启动rpcbind,再启动nfs;如果服务器自身已经安装过NFS,那就用restart重启两个服务):
[root@local /]# service rpcbind start
Starting rpcbind: [ OK ]
[root@local /]# service nfs start
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS mountd: [ OK ]
Stopping RPC idmapd: [ OK ]
Starting RPC idmapd: [ OK ]
Starting NFS daemon: [ OK ]
[root@local /]#6、设置NFS服务开机自启动:
[root@local /]# chkconfig rpcbind on
[root@local /]# chkconfig nfs on

三、客户端挂载配置

1、创建一个挂载点:
 
[root@localhost ~]# mkdir /mnt/store2、查看NFS服务器上的共享:
[root@localhost /]# showmount -e 192.168.0.10
Export list for 192.168.0.10:
/sharestore *3、挂载:[root@localhost ~]# mount -t nfs 192.168.0.10:/sharestore /mnt/store4、查看已挂载共享:
[root@localhost ~]# mount
/dev/mapper/VolGroup-lv_root on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext4 (rw)
/dev/mapper/VolGroup-lv_home on /home type ext4 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
nfsd on /proc/fs/nfsd type nfsd (rw)
192.168.0.10:/mailstore1/ on /mailstore_new type nfs (rw,vers=4,addr=192.168.0.10,clientaddr=192.168.0.11) 查看全部
nfs.png

如果生产环境,可以利用heartbeta或者keepalived作高可用,下面介绍一下nfs服务安装过程。
 


一、安装环境


NFS服务器:CentOS6.5 192.168.0.10
NFS客户端:CentOS6.5 192.168.0.11
 


二、服务器端安装配置​


1、先用rpm -qa命令查看所需安装包(nfs-utils、rpcbind)是否已经安装:
[root@local /]# rpm -qa | grep "rpcbind"
rpcbind-0.2.0-11.el6.x86_64
[root@local /]# rpm -qa | grep "nfs"
nfs-utils-1.2.3-39.el6.x86_64
nfs4-acl-tools-0.3.3-6.el6.x86_64
nfs-utils-lib-1.1.5-6.el6.x86_64
2、如查询结果如上,说明服务器自身已经安装了NFS,如果没有安装,则用yum命令来安装:
[root@local /]# yum -y install nfs-utils rpcbind
3、创建共享目录:
[root@local /]# mkdir /sharestore
4、NFS共享文件路径配置:
编辑/etc/exports添加下面一行,添加后保存退出。
 
[root@local /]# vi /etc/exports
/sharestore *(rw,sync,no_root_squash)
/sharestore   10.10.0.0/8(rw,sync,no_subtree_check,anonuid=48,anongid=48)
你也可以指定可以访问网段和用户id。
 
5、启动NFS服务(先启动rpcbind,再启动nfs;如果服务器自身已经安装过NFS,那就用restart重启两个服务):
[root@local /]# service rpcbind start
Starting rpcbind: [ OK ]
[root@local /]# service nfs start
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS mountd: [ OK ]
Stopping RPC idmapd: [ OK ]
Starting RPC idmapd: [ OK ]
Starting NFS daemon: [ OK ]
[root@local /]#
6、设置NFS服务开机自启动:
[root@local /]# chkconfig rpcbind on
[root@local /]# chkconfig nfs on


三、客户端挂载配置


1、创建一个挂载点:
 
[root@localhost ~]# mkdir /mnt/store
2、查看NFS服务器上的共享:
[root@localhost /]# showmount -e 192.168.0.10
Export list for 192.168.0.10:
/sharestore *
3、挂载:
[root@localhost ~]# mount -t nfs 192.168.0.10:/sharestore /mnt/store
4、查看已挂载共享:
[root@localhost ~]# mount
/dev/mapper/VolGroup-lv_root on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw)
/dev/sda1 on /boot type ext4 (rw)
/dev/mapper/VolGroup-lv_home on /home type ext4 (rw)
none on /proc/sys/fs/binfmt_misc type binfmt_misc (rw)
sunrpc on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw)
nfsd on /proc/fs/nfsd type nfsd (rw)
192.168.0.10:/mailstore1/ on /mailstore_new type nfs (rw,vers=4,addr=192.168.0.10,clientaddr=192.168.0.11)

设置iptables NAT出外网

Ansible 发表了文章 • 0 个评论 • 151 次浏览 • 2017-04-22 17:01 • 来自相关话题

有时候云上部署环境,不能动态自设路由,没有公网ip地址的服务器,只能通过NAT的方式出外网,下面就记录一下设置过程。

当前状态

服务器A只有一个内网IP,不能上外网,内网IP与服务器B内网相通;服务器B有一个内网IP和公网IP。想实现服务器A也能上外网。服务器A:内网网卡:eth0 内网IP:192.168.0.10

服务器B:内网网卡:eth0 内网IP:192.168.0.20
外网网卡:eth1 外网IP:203.195.32.138

实现方法

1、在可以上外网的服务器B上,开启路由转发功能echo 1 > /proc/sys/net/ipv4/ip_forward注:上面命令在服务器重启之后会失效,可以编辑/etc/rc.d/rc.local把上面命令添加到最底部,实现开启自动执行。
 
或者进行如下操作:编辑/etc/sysctl.conf
找到net.ipv4.ip_forward = 0 修改为 net.ipv4.ip_forward = 1 最后保存。

执行sysctl -p命令使配置生效:
# sysctl -p
2、在可以上外网的服务器B上执行添加SNAT规则# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.10 -j SNAT --to 203.195.32.138如果想让整个网段都通过服务器B上外网,修改上面规则命令中-s 192.168.0.10为-s 192.168.0.0/24,然后把想上外网的服务器默认网关改成192.168.0.20就可以了。
 
3、保存刚添加的iptables规则# service iptables save
4、在需要上外网的服务器A上,修改内网网卡eth0的默认网关为192.168.0.20# route add default gw 192.168.0.20
修改后,查看路由表,确认已修改成功,测试已经可以上外网了# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 192.168.0.20 0.0.0.0 UG 0 0 0 eth0测试你ping一下baidu.com 就好。 查看全部
有时候云上部署环境,不能动态自设路由,没有公网ip地址的服务器,只能通过NAT的方式出外网,下面就记录一下设置过程。


当前状态


服务器A只有一个内网IP,不能上外网,内网IP与服务器B内网相通;服务器B有一个内网IP和公网IP。想实现服务器A也能上外网。
服务器A:内网网卡:eth0  内网IP:192.168.0.10

服务器B:内网网卡:eth0 内网IP:192.168.0.20
外网网卡:eth1 外网IP:203.195.32.138


实现方法


1、在可以上外网的服务器B上,开启路由转发功能
echo 1 > /proc/sys/net/ipv4/ip_forward
:上面命令在服务器重启之后会失效,可以编辑/etc/rc.d/rc.local把上面命令添加到最底部,实现开启自动执行。
 
或者进行如下操作:
编辑/etc/sysctl.conf
找到net.ipv4.ip_forward = 0 修改为 net.ipv4.ip_forward = 1 最后保存。

执行sysctl -p命令使配置生效:
# sysctl -p

2、在可以上外网的服务器B上执行添加SNAT规则
# iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.10 -j SNAT --to 203.195.32.138
如果想让整个网段都通过服务器B上外网,修改上面规则命令中-s 192.168.0.10为-s 192.168.0.0/24,然后把想上外网的服务器默认网关改成192.168.0.20就可以了。
 
3、保存刚添加的iptables规则
# service iptables save

4、在需要上外网的服务器A上,修改内网网卡eth0的默认网关为192.168.0.20
# route add default gw 192.168.0.20

修改后,查看路由表,确认已修改成功,测试已经可以上外网了
# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 192.168.0.20 0.0.0.0 UG 0 0 0 eth0
测试你ping一下baidu.com 就好。

​部署SaaS向云计算转型 网络安全需先行

OT学习平台 发表了文章 • 0 个评论 • 267 次浏览 • 2017-04-20 16:18 • 来自相关话题

云计算解决方案可让企业快速部署服务以及降低总体拥有成本,这也是为什么首席信息官(CIO)转向软件即服务(SaaS)来提供有效高效服务的原因。
然而,尽管云计算解决方案有很多优势,但企业还必须考虑部署SaaS的安全影响。成功云计算转型的关键是在转移到SaaS解决方案时使用适当的安全控制。
部署SaaS最佳做法
部署SaaS并不会自动保证整体基础设施的安全性,企业应该查看需要保护的服务的安全控制情况。例如,你必须了解针对客户关系管理(CRM)解决方案的攻击的特定后果。同时,你必须确保你的安全信息和事件管理(SIEM)解决方案能够从这个CRM中收集数据。
同样重要的是管理联合身份,因为很多SaaS解决方案要求不同类型的身份验证。强迫用户输入多个密码并不足以构建正确的安全文化。
IT经理通常会基于不现实的战略决策来决定是否部署云计算交付模型。但如果公司决定不允许其员工利用云计算服务,可能为时已晚。云计算服务已经在企业功能中使用,例如很多库使用云端应用程序接口(API),而员工早就开始使用云应用。
复杂的生态系统
云应用的生命周期必须包含动态安全分析,这些应用是复杂生态系统的一部分。它们可能今天很安全,第二天就布满漏洞,这主要取决于生态系统的状态。
企业应该专注于向服务安装安全控制,确保部署这些控制的技术不会依靠交付模型。否则,你可能会被迫部署不是基于战略决策的技术和业务模型,只是为了挽救以前的投资。为内部部署和云服务提供相同的安全控制是良好安全策略的关键因素。
SaaS提供商的责任
应用是恶意攻击者执行网络攻击的窗口,因此,安全应该成为这些应用开发周期的一部分。SaaS提供商需要不断测试他们的产品,并根据安全响应专家制定的流程和最佳做法对漏洞作出响应。
供应商还应该在非常坚实的基础设施即服务(IaaS)以及平台即服务(PaaS)上提供SaaS,最后,SaaS提供商还必须遵守隐私和数据管理法规。
OTPUB直播活动又双叒叕来喽!

直播主题

Excel的“天上人间”-“出台”到PPT的动态图表

直播时间

2017年4月25日 14:00-15:00

点击参与报名>>>
http://www.otpub.com/special/Excel0425/excel0425_baoming.html 查看全部

云计算解决方案可让企业快速部署服务以及降低总体拥有成本,这也是为什么首席信息官(CIO)转向软件即服务(SaaS)来提供有效高效服务的原因。
然而,尽管云计算解决方案有很多优势,但企业还必须考虑部署SaaS的安全影响。成功云计算转型的关键是在转移到SaaS解决方案时使用适当的安全控制。
部署SaaS最佳做法
部署SaaS并不会自动保证整体基础设施的安全性,企业应该查看需要保护的服务的安全控制情况。例如,你必须了解针对客户关系管理(CRM)解决方案的攻击的特定后果。同时,你必须确保你的安全信息和事件管理(SIEM)解决方案能够从这个CRM中收集数据。
同样重要的是管理联合身份,因为很多SaaS解决方案要求不同类型的身份验证。强迫用户输入多个密码并不足以构建正确的安全文化。
IT经理通常会基于不现实的战略决策来决定是否部署云计算交付模型。但如果公司决定不允许其员工利用云计算服务,可能为时已晚。云计算服务已经在企业功能中使用,例如很多库使用云端应用程序接口(API),而员工早就开始使用云应用。
复杂的生态系统
云应用的生命周期必须包含动态安全分析,这些应用是复杂生态系统的一部分。它们可能今天很安全,第二天就布满漏洞,这主要取决于生态系统的状态。
企业应该专注于向服务安装安全控制,确保部署这些控制的技术不会依靠交付模型。否则,你可能会被迫部署不是基于战略决策的技术和业务模型,只是为了挽救以前的投资。为内部部署和云服务提供相同的安全控制是良好安全策略的关键因素。
SaaS提供商的责任
应用是恶意攻击者执行网络攻击的窗口,因此,安全应该成为这些应用开发周期的一部分。SaaS提供商需要不断测试他们的产品,并根据安全响应专家制定的流程和最佳做法对漏洞作出响应。
供应商还应该在非常坚实的基础设施即服务(IaaS)以及平台即服务(PaaS)上提供SaaS,最后,SaaS提供商还必须遵守隐私和数据管理法规。
OTPUB直播活动又双叒叕来喽!

直播主题

Excel的“天上人间”-“出台”到PPT的动态图表

直播时间

2017年4月25日 14:00-15:00

点击参与报名>>>
http://www.otpub.com/special/Excel0425/excel0425_baoming.html

ext4文件系统的delalloc选项造成单次写延迟增加的分析

OS小编 发表了文章 • 0 个评论 • 162 次浏览 • 2017-04-18 09:30 • 来自相关话题

最近我们的服务进程遇到kill -15后处于Z的状态,变为了僵尸进程,经过/proc/{thread_id}/stack查看其上线程的栈,发现是卡在了fwrite的过程中,而我们的系统中所有文件系统挂载参数都使用了delalloc参数,怀疑是这个原因:ext4挂载的时候打开了delalloc选项,然后系统在没有分配磁盘块的情况下写写写,到page cache被回写到磁盘时,发现磁盘已经满了,没办法分配新的磁盘块了,就Hang住了。
 
这篇文章是淘宝内核组的刘峥同学在内部技术论坛上发表的一篇文章,但是由于刘峥同学目前没有blog,征得本人同意,贴在我的blog上,如果大家喜欢,请去新浪微博关注他。:)
 
日前线上在升级到Ext4文件系统后出现应用写操作延迟开销增大的问题。造成这一问题的根源目前已经查明,是由于Ext4文件系统的一个新特性——Delay Allocation造成的。(后面简称delalloc)

在详细分析这一问题之前,先来介绍一下Ext4文件系统的delalloc特性。这一特性简要概括起来就是将以前在buffer IO中每次写操作都会涉及的磁盘块分配过程推迟到数据回写时再进行。我们知道,在进行Buffer Write时,系统的实际操作仅仅是为这些数据在操作系统内分配内存页(page cache)并保存这些数据,等待用户调用fsync等操作强制刷新或者等待系统触发定时回写过程。在数据拷贝到page cache这一过程中,系统会为这些数据在磁盘上分配对应的磁盘块。

而在使用delalloc后,上面的流程会略有不同,在每次Buffer Write时,数据会被保存到page cache中,但是系统并不会为这些数据分配相应的磁盘块,仅仅会查询是否有已经为这些数据分配过磁盘块,以便决定后面是否需要为这些数据分配磁盘块。在用户调用fsync或者系统触发回写过程时,系统会尝试为标记需要分配磁盘块的这些数据分配磁盘块。这样,文件系统可以为这些属于同一个文件的数据分配尽量连续的磁盘空间,从而优化后续文件的访问性能(因为传统机械硬盘顺序读写的性能要比随机读写好很多)。

了解完delalloc特性的工作过程后,我们开始分析线上遇到的问题。线上应用的I/O模式可以简化为一个单线程追加写操作的程序,每秒写入2、3M数据,写操作后等待系统自动将数据回写到磁盘。在使用delalloc后,每次Buffer Write操作,系统都会去查询数据是否分配了磁盘块,这一过程需要获得一把读锁 (i_data_sem)。由于这时还没有触发回写操作,因此可以顺利获取i_data_sem,系统完成数据拷贝工作,并返回。由于仅仅是内存拷贝的过程,所以这一操作速度相当快。当系统开始进行回写操作时,系统会成批为数据分配磁盘块,这一过程同样需要获取i_data_sem,并且需要加写锁​以保证数据的一致性。由于使用delalloc后,需要分配的磁盘块比nodelalloc情况下多很多(nodelalloc情况下每5秒文件系统会提交日志触发回写;delalloc情况下,系统会在约每30秒左右触发一次回写),因此这一延迟时间较长。如果这时应用程序进行一次Buffer Write,则该操作在尝试获得i_data_sem时会等待上述磁盘块分配完成。由此造成写操作等待很长时间,从而影响应用程序的响应延迟。

在上面的分析中已经提到,delalloc是将多次磁盘块分配的过程合并到一次中来进行,那么是否真如预想的那样,delalloc的平均延迟会小于nodelalloc的情况呢?我们使用fio来做如下测试:设置bs=4k,单线程每秒追加写入5M,程序运行3分钟,我们来看一下最后fio对延迟的统计结果:
delalloc:
lat (usec): min=2 , max=193466 , avg= 5.86, stdev=227.91

nodelalloc:
lat (usec): min=3 , max=16388 , avg= 7.00, stdev=28.92从上面的统计结果看,写操作的平均延迟:打开delalloc后为5.86us,关闭delalloc后为7.00us;最小延迟delalloc为2us,nodelalloc为3us;但是最大延迟delalloc为193.466ms,nodelalloc下仅为16.388ms。可见delalloc确实将多个写操作请求集中到了一起来进行。因此在提供较低平均延迟的情况下,会造成某次写操作的延迟较大。

通过上面的分析可以看到,目前会受到Ext4的delalloc特性影响的应用必须具备如下条件:
Buffer IO写操作过程中会涉及磁盘块的分配,主要是记录日志这类追加写操作;每次写操作后没有刷新数据,而是等待系统自动进行回写;对延迟有较高要求。
 
解决方法:关闭delalloc
1、mount -t ext4 -o remount,nodelalloc /${dev} /${mnt};
2、编辑/etc/fstab中相关mount项,添加nodelalloc挂载参数

分享原文:http://www.cnblogs.com/cobbliu/p/5603472.html   查看全部
最近我们的服务进程遇到kill -15后处于Z的状态,变为了僵尸进程,经过/proc/{thread_id}/stack查看其上线程的栈,发现是卡在了fwrite的过程中,而我们的系统中所有文件系统挂载参数都使用了delalloc参数,怀疑是这个原因:ext4挂载的时候打开了delalloc选项,然后系统在没有分配磁盘块的情况下写写写,到page cache被回写到磁盘时,发现磁盘已经满了,没办法分配新的磁盘块了,就Hang住了。
 
这篇文章是淘宝内核组的刘峥同学在内部技术论坛上发表的一篇文章,但是由于刘峥同学目前没有blog,征得本人同意,贴在我的blog上,如果大家喜欢,请去新浪微博关注他。:)
 
日前线上在升级到Ext4文件系统后出现应用写操作延迟开销增大的问题。造成这一问题的根源目前已经查明,是由于Ext4文件系统的一个新特性——Delay Allocation造成的。(后面简称delalloc)

在详细分析这一问题之前,先来介绍一下Ext4文件系统的delalloc特性。这一特性简要概括起来就是将以前在buffer IO中每次写操作都会涉及的磁盘块分配过程推迟到数据回写时再进行。我们知道,在进行Buffer Write时,系统的实际操作仅仅是为这些数据在操作系统内分配内存页(page cache)并保存这些数据,等待用户调用fsync等操作强制刷新或者等待系统触发定时回写过程。在数据拷贝到page cache这一过程中,系统会为这些数据在磁盘上分配对应的磁盘块。

而在使用delalloc后,上面的流程会略有不同,在每次Buffer Write时,数据会被保存到page cache中,但是系统并不会为这些数据分配相应的磁盘块,仅仅会查询是否有已经为这些数据分配过磁盘块,以便决定后面是否需要为这些数据分配磁盘块。在用户调用fsync或者系统触发回写过程时,系统会尝试为标记需要分配磁盘块的这些数据分配磁盘块。这样,文件系统可以为这些属于同一个文件的数据分配尽量连续的磁盘空间,从而优化后续文件的访问性能(因为传统机械硬盘顺序读写的性能要比随机读写好很多)。

了解完delalloc特性的工作过程后,我们开始分析线上遇到的问题。线上应用的I/O模式可以简化为一个单线程追加写操作的程序,每秒写入2、3M数据,写操作后等待系统自动将数据回写到磁盘。在使用delalloc后,每次Buffer Write操作,系统都会去查询数据是否分配了磁盘块,这一过程需要获得一把读锁 (i_data_sem)。由于这时还没有触发回写操作,因此可以顺利获取i_data_sem,系统完成数据拷贝工作,并返回。由于仅仅是内存拷贝的过程,所以这一操作速度相当快。当系统开始进行回写操作时,系统会成批为数据分配磁盘块,这一过程同样需要获取i_data_sem,并且需要加写锁​以保证数据的一致性。由于使用delalloc后,需要分配的磁盘块比nodelalloc情况下多很多(nodelalloc情况下每5秒文件系统会提交日志触发回写;delalloc情况下,系统会在约每30秒左右触发一次回写),因此这一延迟时间较长。如果这时应用程序进行一次Buffer Write,则该操作在尝试获得i_data_sem时会等待上述磁盘块分配完成。由此造成写操作等待很长时间,从而影响应用程序的响应延迟。

在上面的分析中已经提到,delalloc是将多次磁盘块分配的过程合并到一次中来进行,那么是否真如预想的那样,delalloc的平均延迟会小于nodelalloc的情况呢?我们使用fio来做如下测试:设置bs=4k,单线程每秒追加写入5M,程序运行3分钟,我们来看一下最后fio对延迟的统计结果:
delalloc:
lat (usec): min=2 , max=193466 , avg= 5.86, stdev=227.91

nodelalloc:
lat (usec): min=3 , max=16388 , avg= 7.00, stdev=28.92
从上面的统计结果看,写操作的平均延迟:打开delalloc后为5.86us,关闭delalloc后为7.00us;最小延迟delalloc为2us,nodelalloc为3us;但是最大延迟delalloc为193.466ms,nodelalloc下仅为16.388ms。可见delalloc确实将多个写操作请求集中到了一起来进行。因此在提供较低平均延迟的情况下,会造成某次写操作的延迟较大。

通过上面的分析可以看到,目前会受到Ext4的delalloc特性影响的应用必须具备如下条件:
  1. Buffer IO
  2. 写操作过程中会涉及磁盘块的分配,主要是记录日志这类追加写操作;
  3. 每次写操作后没有刷新数据,而是等待系统自动进行回写;
  4. 对延迟有较高要求。

 
解决方法:关闭delalloc
1、mount -t ext4 -o remount,nodelalloc /${dev} /${mnt};
2、编辑/etc/fstab中相关mount项,添加nodelalloc挂载参数


分享原文:http://www.cnblogs.com/cobbliu/p/5603472.html  


2017年公有云基础设施支出将会超过私有云

OT学习平台 发表了文章 • 0 个评论 • 133 次浏览 • 2017-04-17 16:57 • 来自相关话题

根据IDC全球季度云计算IT基础架构的最新预测,IT基础架构产品(服务器,企业存储和以太网交换机)的总支出用于部署在云环境中的支出,2017年将同比增长15.3%至417亿美元。公有云数据中心占这一支出的大部分,占60.5%,而私有云环境将占支出的14.9%。本地私有云将占私有云IT基础设施支出的62.3%,并将在2017年同比增长13.1%。
2017年公有云基础设施支出超过私有云
云计算IT基础设施投资将在所有地区增加,而大多数地区预计在所有三个技术领域的非云部署支出将会减少。总体而言,全球在传统的非云计算IT基础架构上的支出将在2017年下降5.3%。然而,它仍将占最终用户支出的最大份额,占比57.9%。
在云环境中,以太网交换机将是增长最快的技术部门,2017年同比增长21.8%,而服务器和企业存储上的支出分别增长17.9%和10.7%。在持续采用基于服务器和软件定义的存储解决方案的过程中,外部存储部门的薄弱环节是企业存储支出放缓的一个重要因素。在所有这三个部分中,部署在场外的IT基础设施的支出将比在内部部署环境中的支出增长得快。
长期来看,IDC预计,外部部署云计算IT支出将以5年复合增长率(CAGR)增长11.7%,到2021年达到472亿美元。公有云数据中心将占该数额的80.4%。与内部部署私有云相结合,云计算IT基础设施的总体支出将以年均11%的速度增长,到2020年将超过非云IT基础架构的支出。内部部署私有云IT基础架构的支出将以年均复合增长率10.3%,而在非云IT(内部和外部组合)的支出将在同期缩短3%的年均复合增长率。
 
OTPUB直播活动又双叒叕来喽!
直播主题
Excel的“天上人间”-“出台”到PPT的动态图表
直播时间
2017年4月25日 14:00-15:00
点击参与报名>>> 查看全部

根据IDC全球季度云计算IT基础架构的最新预测,IT基础架构产品(服务器,企业存储和以太网交换机)的总支出用于部署在云环境中的支出,2017年将同比增长15.3%至417亿美元。公有云数据中心占这一支出的大部分,占60.5%,而私有云环境将占支出的14.9%。本地私有云将占私有云IT基础设施支出的62.3%,并将在2017年同比增长13.1%。
2017年公有云基础设施支出超过私有云
云计算IT基础设施投资将在所有地区增加,而大多数地区预计在所有三个技术领域的非云部署支出将会减少。总体而言,全球在传统的非云计算IT基础架构上的支出将在2017年下降5.3%。然而,它仍将占最终用户支出的最大份额,占比57.9%。
在云环境中,以太网交换机将是增长最快的技术部门,2017年同比增长21.8%,而服务器和企业存储上的支出分别增长17.9%和10.7%。在持续采用基于服务器和软件定义的存储解决方案的过程中,外部存储部门的薄弱环节是企业存储支出放缓的一个重要因素。在所有这三个部分中,部署在场外的IT基础设施的支出将比在内部部署环境中的支出增长得快。
长期来看,IDC预计,外部部署云计算IT支出将以5年复合增长率(CAGR)增长11.7%,到2021年达到472亿美元。公有云数据中心将占该数额的80.4%。与内部部署私有云相结合,云计算IT基础设施的总体支出将以年均11%的速度增长,到2020年将超过非云IT基础架构的支出。内部部署私有云IT基础架构的支出将以年均复合增长率10.3%,而在非云IT(内部和外部组合)的支出将在同期缩短3%的年均复合增长率。
 
OTPUB直播活动又双叒叕来喽!
直播主题
Excel的“天上人间”-“出台”到PPT的动态图表
直播时间
2017年4月25日 14:00-15:00
点击参与报名>>>

一个成熟的自动化运维系统应具备哪些功能?

Nock 发表了文章 • 0 个评论 • 223 次浏览 • 2017-04-15 16:47 • 来自相关话题

结合现在云计算和DevOps的发展趋势,我觉得一个成熟的自动化运维平台应该包括以下的特性:
一、支持混合云的CMDB​
现在越来越多的服务器都转到了云上,而主流的公有云、私有云平台都拥有比较完备的资源管理的API,这些API也就是构建一个自动化CMDB的基础。

新一代的自动化运维平台应该是可以基于这些API来自动维护和管理相关的服务器、存储、网络、负载均衡的资源的。
通过API对资源的操作都应该被作为操作日志记录下来,以备作为后续操作审计的基础数据。

CMDB这个东西听上去是老生常谈,但这个确实是所有运维工具的基础设施。而基于开源工具做运维平台最大的麻烦,就是如何在各个工具之间把CMDB统一起来。CMDB不统一起来,就意味着一旦要增加一台服务器,可能要在各个运维工具里面都要同步一下,这个还是非常折腾滴。

二、比较完备的监控+应用性能分析(APM)
能支持对平台的可用性、服务器的性能、各种服务(web服务、应用服务、数据库服务)的性能进行监控。做的好一些应该能进行更深入、或者关联性的性能分析。

现在市面上一般都会将资源性能监控和应用性能监控(APM)混合着讲,这里面的产品确实也有很多都是重叠的,两方面都会涉及到。

开源的性能监控系统主流有的Zabbix、Nagios,国产的开源监控平台有小米OpenFalcon,但这些基本都只是做基本的资源监控(服务器,磁盘、网络等)和简单的服务软件的性能监控(中间件,数据库等)。

而市面上的APM系统更主打的功能是应用性能分析,比如能精确定位到某个应用的URL的访问速度快慢,某些SQL执行速度的快慢,这些对于开发人员和运维人员快速定位问题还是很有帮助的。

APM这方面的商业工具,国外比较主流的有New Reclic、Dynatrace,国内的也就是透视宝、Oneapm、听云等,他们也提供了API进行集成。

APM这方面的开源工具有pinpoint(一个韩国团队开源的),zipkin(twitter开源),cat(大众点评开源)。
 
三、有一个还不错UI的批量运维工具
在业务发展比较快的情况下,从几台服务器,到几十台服务器,再到几百台服务器,批量运维的需求很自然就产生了,老板也希望越少的人干越多的活。

现在也有不少开源的批量运维工具,也都比较成熟了,比如puppet、chef、ansible、saltstack。
puppet和chef都是ruby做的,实话实说,ruby的熟手市面上很少,比python不是难招一点。

我个人比较推荐使用ansible或者saltstack,这两个系统都是python写的,代码质量和社区活跃度都挺不错的。
ansible有官方的web ui——Tower,但实话实说不好用,所以我们也在重新做一套自己用起来更顺手的WEB UI。
 
四、日志集中分析工具
线上系统最常规的问题定位方式,就是日志分析了。
随着服务器的增多,日志的分析定位也成为一个难点和痛点(想象一下,系统出故障之后,要去几十甚至数百个节点去上去查日志,是有多折腾)。

国内有一家叫日志易的公司,是专门做日志分析方面的运维工具的。
另外还有一家log insight,也是做这个领域,但产品好像还处于beta阶段。

日志分析这个领域现在是一个热点,现在的开源方案也比较多了,比如著名的ELKStack,还有Flume+Kafka+Storm的体系。
上面这两个方案相对重一些,部署比较复杂,网上介绍的文章也不少。

比较轻量级的开源日志集中采集方案有python做的Sentry,他是通过改造各种语言的日志采集框架来实现日志的集中采集,各种主流的开发语言的日志框架都支持得很完整了,比如java的log4j和logpack。
 
Sentry的官网在此:Sentry - Track exceptions with modern error logging for JavaScript, Python, Ruby, Java, and Node.js.
 
五、持续集成和发布工具
这方面其实比较难有统一的需求,很多公司集成发布的做法都差异挺大的。持续集成方面,一般用jekins的比较多,这方面网上介绍的文章也很多。

而如何把打好的包发布至各台服务器,则可以通过批量运维工具或者脚本来完成了。版本发布的过程涉及到很多细节,包括了版本文件的上传、分发、版本管理、回滚等各种操作。

对于一般不太复杂的项目,我比较推荐的做法是把打包好的文件上传到svn or git上,然后通过脚本在各台服务器上进行发布操作就行了,这样其实是利用了SVN or GIT来完成文件的上传、分发、版本管理、回滚等各种操作。
 
六、安全漏洞扫描工具
现在一个稍微有点知名度的系统,都会遭受各种各样的安全攻击的折磨。

一般的公司不太可能请得起专职的安全工程师,所以运维工程师最好能自己借助一些安全扫描工具来发现自己系统的漏洞。

安全工具方面我了解不多,不太熟这个领域的开源工具。
 
之前乌云网推出过一个SaaS化的漏扫平台——唐朝巡航,有对外提供漏洞扫描的API,不过最近乌云网一直在升级,所以也就暂时无法调用了。个人觉得,如果上述功能都有了,基本上大部分中小规模企业的日常运维工作的高频操作都覆盖到了。

如果是比较大的互联网企业,或者还有一些特殊的业务需求,那就具体问题具体分析了。
作者:刀把五
链接:https://www.zhihu.com/question/23228213/answer/116940889  
来源:知乎 查看全部
结合现在云计算和DevOps的发展趋势,我觉得一个成熟的自动化运维平台应该包括以下的特性:
一、支持混合云的CMDB​
现在越来越多的服务器都转到了云上,而主流的公有云、私有云平台都拥有比较完备的资源管理的API,这些API也就是构建一个自动化CMDB的基础。

新一代的自动化运维平台应该是可以基于这些API来自动维护和管理相关的服务器、存储、网络、负载均衡的资源的。
通过API对资源的操作都应该被作为操作日志记录下来,以备作为后续操作审计的基础数据。

CMDB这个东西听上去是老生常谈,但这个确实是所有运维工具的基础设施。而基于开源工具做运维平台最大的麻烦,就是如何在各个工具之间把CMDB统一起来。CMDB不统一起来,就意味着一旦要增加一台服务器,可能要在各个运维工具里面都要同步一下,这个还是非常折腾滴。

二、比较完备的监控+应用性能分析(APM)
能支持对平台的可用性、服务器的性能、各种服务(web服务、应用服务、数据库服务)的性能进行监控。做的好一些应该能进行更深入、或者关联性的性能分析。

现在市面上一般都会将资源性能监控和应用性能监控(APM)混合着讲,这里面的产品确实也有很多都是重叠的,两方面都会涉及到。

开源的性能监控系统主流有的Zabbix、Nagios,国产的开源监控平台有小米OpenFalcon,但这些基本都只是做基本的资源监控(服务器,磁盘、网络等)和简单的服务软件的性能监控(中间件,数据库等)。

而市面上的APM系统更主打的功能是应用性能分析,比如能精确定位到某个应用的URL的访问速度快慢,某些SQL执行速度的快慢,这些对于开发人员和运维人员快速定位问题还是很有帮助的。

APM这方面的商业工具,国外比较主流的有New Reclic、Dynatrace,国内的也就是透视宝、Oneapm、听云等,他们也提供了API进行集成。

APM这方面的开源工具有pinpoint(一个韩国团队开源的),zipkin(twitter开源),cat(大众点评开源)。
 
三、有一个还不错UI的批量运维工具
在业务发展比较快的情况下,从几台服务器,到几十台服务器,再到几百台服务器,批量运维的需求很自然就产生了,老板也希望越少的人干越多的活。

现在也有不少开源的批量运维工具,也都比较成熟了,比如puppet、chef、ansible、saltstack。
puppet和chef都是ruby做的,实话实说,ruby的熟手市面上很少,比python不是难招一点。

我个人比较推荐使用ansible或者saltstack,这两个系统都是python写的,代码质量和社区活跃度都挺不错的。
ansible有官方的web ui——Tower,但实话实说不好用,所以我们也在重新做一套自己用起来更顺手的WEB UI。
 
四、日志集中分析工具
线上系统最常规的问题定位方式,就是日志分析了。
随着服务器的增多,日志的分析定位也成为一个难点和痛点(想象一下,系统出故障之后,要去几十甚至数百个节点去上去查日志,是有多折腾)。

国内有一家叫日志易的公司,是专门做日志分析方面的运维工具的。
另外还有一家log insight,也是做这个领域,但产品好像还处于beta阶段。

日志分析这个领域现在是一个热点,现在的开源方案也比较多了,比如著名的ELKStack,还有Flume+Kafka+Storm的体系。
上面这两个方案相对重一些,部署比较复杂,网上介绍的文章也不少。

比较轻量级的开源日志集中采集方案有python做的Sentry,他是通过改造各种语言的日志采集框架来实现日志的集中采集,各种主流的开发语言的日志框架都支持得很完整了,比如java的log4j和logpack。
 
Sentry的官网在此:Sentry - Track exceptions with modern error logging for JavaScript, Python, Ruby, Java, and Node.js.
 
五、持续集成和发布工具
这方面其实比较难有统一的需求,很多公司集成发布的做法都差异挺大的。持续集成方面,一般用jekins的比较多,这方面网上介绍的文章也很多。

而如何把打好的包发布至各台服务器,则可以通过批量运维工具或者脚本来完成了。版本发布的过程涉及到很多细节,包括了版本文件的上传、分发、版本管理、回滚等各种操作。

对于一般不太复杂的项目,我比较推荐的做法是把打包好的文件上传到svn or git上,然后通过脚本在各台服务器上进行发布操作就行了,这样其实是利用了SVN or GIT来完成文件的上传、分发、版本管理、回滚等各种操作。
 
六、安全漏洞扫描工具
现在一个稍微有点知名度的系统,都会遭受各种各样的安全攻击的折磨。

一般的公司不太可能请得起专职的安全工程师,所以运维工程师最好能自己借助一些安全扫描工具来发现自己系统的漏洞。

安全工具方面我了解不多,不太熟这个领域的开源工具。
 
之前乌云网推出过一个SaaS化的漏扫平台——唐朝巡航,有对外提供漏洞扫描的API,不过最近乌云网一直在升级,所以也就暂时无法调用了。个人觉得,如果上述功能都有了,基本上大部分中小规模企业的日常运维工作的高频操作都覆盖到了。

如果是比较大的互联网企业,或者还有一些特殊的业务需求,那就具体问题具体分析了。
作者:刀把五
链接:https://www.zhihu.com/question/23228213/answer/116940889  
来源:知乎