使用SecureCRT进行端口转发
总共3台机器,我的笔记本,跳转机器,内网服务器:
我的笔记本和内网服务器是不能直连的,必须通过跳板机
每次都要先登陆跳板机,然后在跳板机上通过SSH的方式登陆至内网服务器进行操作是一件特别麻烦的事,并且,如果我在内网服务器的8080端口启动了一个web服务,该如何访问呢?
端口转发的意思是,将所有发送至IP1:port1的请求全部转发至IP2:port2
首先配置至跳板机(150.236.223.72:22)的连接:
配置完成后选择Connect连接至跳板机,输入密码后可选择“Save password”以方便以后使用
一,直接连接至内网服务器
选择“Options” -> "Session Options..."
在左侧边栏中选择“Connection” -> "Port Forwarding",选择“add...”添加一条新的转发规则
添加本任意端口(最好是1024之上的端口)至内网服务器22端口的转发规则
然后选择“OK”,要想配置生效,需要关闭当前连接重新连一次,此时,只要该连接处于连接状态,所有本地(127.0.0.1)2222的请求都会通过跳板机(150.236.223.72)转发至内网服务器(10.170.67.234)的22端口
为了验证配置的正确性,创建一条127.0.0.1:2222的连接(此时连接的username和passward为内网服务器的用户名和密码):
点击“Connect”后,可以发现直接登录至内网服务器
SFTP同样使用22端口,所以此时也可通过127.0.0.1:2222向内网服务器发送文件或从内网服务器下载文件(FileZilla)
Status: Connecting to 127.0.0.1:2222...
Response: fzSftp started
Command: open "root@127.0.0.1" 2222
Command: Pass: *******
Status: Connected to 127.0.0.1
Status: Retrieving directory listing...
Command: pwd
Response: Current directory is: "/root"
Command: ls
Status: Listing directory /root
Status: Calculating timezone offset of server...
Command: mtime ".rhosts"
Response: 1413279106
Status: Timezone offsets: Server: 0 seconds. Local: 28800 seconds. Difference: 28800 seconds.
Status: Directory listing successful
二,访问内网服务器上的web应用
在至跳板机的连接上添加本任意端口(最好是1024之上的端口)至内网服务器8080端口的转发规则
配置完成后同样需要重新连接,此时就可以通过http://127.0.0.1:8080直接访问内网服务器上8080端口启动的web服务了
特别需要注意的是:跳板机的连接关闭,端口转发即失效
【开发规范】规范文档:MySQL规范2
1. 规范背景与目的
MySQL数据库与 Oracle、 SQL Server 等数据库相比,有其内核上的优势与劣势。我们在使用MySQL数据库的时候需要遵循一定规范,扬长避短。本规范旨在帮助或指导RD、QA、OP等技术人员做出适合线上业务的数据库设计。在数据库变更和处理流程、数据库表设计、SQL编写等方面予以规范,从而为公司业务系统稳定、健康地运行提供保障。
2. 设计规范
2.1 数据库设计
以下所有规范会按照【高危】、【强制】、【建议】三个级别进行标注,遵守优先级从高到低。
对于不满足【高危】和【强制】两个级别的设计,DBA会强制打回要求修改。
2.1.1 库名
- 【强制】库的名称必须控制在32个字符以内,相关模块的表名与表名之间尽量提现join的关系,如user表和user_login表。
- 【强制】库的名称格式:业务系统名称_子系统名,同一模块使用的表名尽量使用统一前缀。
- 【强制】一般分库名称命名格式是
库通配名_编号,编号从0开始递增,比如wenda_001以时间进行分库的名称格式是“库通配名_时间” - 【强制】创建数据库时必须显式指定字符集,并且字符集只能是utf8或者utf8mb4。创建数据库SQL举例:
create database db1 default character set utf8;。
2.1.2 表结构
- 【强制】表和列的名称必须控制在32个字符以内,表名只能使用字母、数字和下划线,一律小写。
- 【强制】表名要求模块名强相关,如师资系统采用”sz”作为前缀,渠道系统采用”qd”作为前缀等。
- 【强制】创建表时必须显式指定字符集为utf8或utf8mb4。
- 【强制】创建表时必须显式指定表存储引擎类型,如无特殊需求,一律为InnoDB。当需要使用除InnoDB/MyISAM/Memory以外的存储引擎时,必须通过DBA审核才能在生产环境中使用。因为Innodb表支持事务、行锁、宕机恢复、MVCC等关系型数据库重要特性,为业界使用最多的MySQL存储引擎。而这是其他大多数存储引擎不具备的,因此首推InnoDB。
- 【强制】建表必须有comment
- 【建议】建表时关于主键:(1)强制要求主键为id,类型为int或bigint,且为
auto_increment(2)标识表里每一行主体的字段不要设为主键,建议设为其他字段如user_id,order_id等,并建立unique key索引(可参考cdb.teacher表设计)。因为如果设为主键且主键值为随机插入,则会导致innodb内部page分裂和大量随机I/O,性能下降。 - 【建议】核心表(如用户表,金钱相关的表)必须有行数据的创建时间字段
create_time和最后更新时间字段update_time,便于查问题。 - 【建议】表中所有字段必须都是
NOT NULL属性,业务可以根据需要定义DEFAULT值。因为使用NULL值会存在每一行都会占用额外存储空间、数据迁移容易出错、聚合函数计算结果偏差等问题。 - 【建议】建议对表里的
blob、text等大字段,垂直拆分到其他表里,仅在需要读这些对象的时候才去select。 - 【建议】反范式设计:把经常需要join查询的字段,在其他表里冗余一份。如
user_name属性在user_account,user_login_log等表里冗余一份,减少join查询。 - 【强制】中间表用于保留中间结果集,名称必须以
tmp_开头。备份表用于备份或抓取源表快照,名称必须以bak_开头。中间表和备份表定期清理。 - 【强制】对于超过100W行的大表进行
alter table,必须经过DBA审核,并在业务低峰期执行。因为alter table会产生表锁,期间阻塞对于该表的所有写入,对于业务可能会产生极大影响。
2.1.3 列数据类型优化
- 【建议】表中的自增列(
auto_increment属性),推荐使用bigint类型。因为无符号int存储范围为-2147483648~2147483647(大约21亿左右),溢出后会导致报错。 - 【建议】业务中选择性很少的状态
status、类型type等字段推荐使用tinytint或者smallint类型节省存储空间。 - 【建议】业务中IP地址字段推荐使用
int类型,不推荐用char(15)。因为int只占4字节,可以用如下函数相互转换,而char(15)占用至少15字节。一旦表数据行数到了1亿,那么要多用1.1G存储空间。
SQL:select inet_aton(\'192.168.2.12\'); select inet_ntoa(3232236044);
PHP:ip2long(‘192.168.2.12’); long2ip(3530427185); - 【建议】不推荐使用
enum,set。 因为它们浪费空间,且枚举值写死了,变更不方便。推荐使用tinyint或smallint。 - 【建议】不推荐使用
blob,text等类型。它们都比较浪费硬盘和内存空间。在加载表数据时,会读取大字段到内存里从而浪费内存空间,影响系统性能。建议和PM、RD沟通,是否真的需要这么大字段。Innodb中当一行记录超过8098字节时,会将该记录中选取最长的一个字段将其768字节放在原始page里,该字段余下内容放在overflow-page里。不幸的是在compact行格式下,原始page和overflow-page都会加载。 - 【建议】存储金钱的字段,建议用
int,程序端乘以100和除以100进行存取。因为int占用4字节,而double占用8字节,空间浪费。 - 【建议】文本数据尽量用
varchar存储。因为varchar是变长存储,比char更省空间。MySQL server层规定一行所有文本最多存65535字节,因此在utf8字符集下最多存21844个字符,超过会自动转换为mediumtext字段。而text在utf8字符集下最多存21844个字符,mediumtext最多存2^24/3个字符,longtext最多存2^32个字符。一般建议用varchar类型,字符数不要超过2700。 - 【建议】时间类型尽量选取
timestamp。因为datetime占用8字节,timestamp仅占用4字节,但是范围为1970-01-01 00:00:01到2038-01-01 00:00:00。更为高阶的方法,选用int来存储时间,使用SQL函数unix_timestamp()和from_unixtime()来进行转换。
详细存储大小参加下图:


2.1.4 索引设计
- 【强制】InnoDB表必须主键为
id int/bigint auto_increment,且主键值禁止被更新。 - 【建议】主键的名称以“
pk_”开头,唯一键以“uk_”或“uq_”开头,普通索引以“idx_”开头,一律使用小写格式,以表名/字段的名称或缩写作为后缀。 - 【强制】InnoDB和MyISAM存储引擎表,索引类型必须为
BTREE;MEMORY表可以根据需要选择HASH或者BTREE类型索引。 - 【强制】单个索引中每个索引记录的长度不能超过64KB。
- 【建议】单个表上的索引个数不能超过7个。
- 【建议】在建立索引时,多考虑建立联合索引,并把区分度最高的字段放在最前面。如列
userid的区分度可由select count(distinct userid)计算出来。 - 【建议】在多表join的SQL里,保证被驱动表的连接列上有索引,这样join执行效率最高。
- 【建议】建表或加索引时,保证表里互相不存在冗余索引。对于MySQL来说,如果表里已经存在
key(a,b),则key(a)为冗余索引,需要删除。
2.1.5 分库分表、分区表
- 【强制】分区表的分区字段(
partition-key)必须有索引,或者是组合索引的首列。 - 【强制】单个分区表中的分区(包括子分区)个数不能超过1024。
- 【强制】上线前RD或者DBA必须指定分区表的创建、清理策略。
- 【强制】访问分区表的SQL必须包含分区键。
- 【建议】单个分区文件不超过2G,总大小不超过50G。建议总分区数不超过20个。
- 【强制】对于分区表执行
alter table操作,必须在业务低峰期执行。 - 【强制】采用分库策略的,库的数量不能超过1024
- 【强制】采用分表策略的,表的数量不能超过4096
- 【建议】单个分表不超过500W行,ibd文件大小不超过2G,这样才能让数据分布式变得性能更佳。
- 【建议】水平分表尽量用取模方式,日志、报表类数据建议采用日期进行分表。
2.1.6 字符集
- 【强制】数据库本身库、表、列所有字符集必须保持一致,为
utf8或utf8mb4。 - 【强制】前端程序字符集或者环境变量中的字符集,与数据库、表的字符集必须一致,统一为
utf8。
2.1.7 程序层DAO设计建议
- 【建议】新的代码不要用model,推荐使用手动拼SQL 绑定变量传入参数的方式。因为model虽然可以使用面向对象的方式操作db,但是其使用不当很容易造成生成的SQL非常复杂,且model层自己做的强制类型转换性能较差,最终导致数据库性能下降。
- 【建议】前端程序连接MySQL或者redis,必须要有连接超时和失败重连机制,且失败重试必须有间隔时间。
- 【建议】前端程序报错里尽量能够提示MySQL或redis原生态的报错信息,便于排查错误。
- 【建议】对于有连接池的前端程序,必须根据业务需要配置初始、最小、最大连接数,超时时间以及连接回收机制,否则会耗尽数据库连接资源,造成线上事故。
- 【建议】对于log或history类型的表,随时间增长容易越来越大,因此上线前RD或者DBA必须建立表数据清理或归档方案。
- 【建议】在应用程序设计阶段,RD必须考虑并规避数据库中主从延迟对于业务的影响。尽量避免从库短时延迟(20秒以内)对业务造成影响,建议强制一致性的读开启事务走主库,或更新后过一段时间再去读从库。
- 【建议】多个并发业务逻辑访问同一块数据(innodb表)时,会在数据库端产生行锁甚至表锁导致并发下降,因此建议更新类SQL尽量基于主键去更新。
- 【建议】业务逻辑之间加锁顺序尽量保持一致,否则会导致死锁。
- 【建议】对于单表读写比大于10:1的数据行或单个列,可以将热点数据放在缓存里(如mecache或redis),加快访问速度,降低MySQL压力。
2.1.8 一个规范的建表语句示例
一个较为规范的建表语句为:
CREATE TABLE user (
`id` bigint(11) NOT NULL AUTO_INCREMENT,
`user_id` bigint(11) NOT NULL COMMENT ‘用户id’
`username` varchar(45) NOT NULL COMMENT \'真实姓名\',
`email` varchar(30) NOT NULL COMMENT ‘用户邮箱’,
`nickname` varchar(45) NOT NULL COMMENT \'昵称\',
`avatar` int(11) NOT NULL COMMENT \'头像\',
`birthday` date NOT NULL COMMENT \'生日\',
`sex` tinyint(4) DEFAULT \'0\' COMMENT \'性别\',
`short_introduce` varchar(150) DEFAULT NULL COMMENT \'一句话介绍自己,最多50个汉字\',
`user_resume` varchar(300) NOT NULL COMMENT \'用户提交的简历存放地址\',
`user_register_ip` int NOT NULL COMMENT ‘用户注册时的源ip’,
`create_time` timestamp NOT NULL COMMENT ‘用户记录创建的时间’,
`update_time` timestamp NOT NULL COMMENT ‘用户资料修改的时间’,
`user_review_status` tinyint NOT NULL COMMENT ‘用户资料审核状态,1为通过,2为审核中,3为未通过,4为还未提交审核’,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_user_id` (`user_id`),
KEY `idx_username`(`username`),
KEY `idx_create_time`(`create_time`,`user_review_status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=\'网站用户基本信息\';
2.2 SQL编写
2.2.1 DML语句
- 【强制】SELECT语句必须指定具体字段名称,禁止写成
*。因为select *会将不该读的数据也从MySQL里读出来,造成网卡压力。且表字段一旦更新,但model层没有来得及更新的话,系统会报错。 - 【强制】insert语句指定具体字段名称,不要写成
insert into t1 values(…),道理同上。 - 【建议】
insert into…values(XX),(XX),(XX)…。这里XX的值不要超过5000个。值过多虽然上线很很快,但会引起主从同步延迟。 - 【建议】SELECT语句不要使用
UNION,推荐使用UNION ALL,并且UNION子句个数限制在5个以内。因为union all不需要去重,节省数据库资源,提高性能。 - 【建议】in值列表限制在500以内。例如
select… where userid in(….500个以内…),这么做是为了减少底层扫描,减轻数据库压力从而加速查询。 - 【建议】事务里批量更新数据需要控制数量,进行必要的sleep,做到少量多次。
- 【强制】事务涉及的表必须全部是innodb表。否则一旦失败不会全部回滚,且易造成主从库同步终端。
- 【强制】写入和事务发往主库,只读SQL发往从库。
- 【强制】除静态表或小表(100行以内),DML语句必须有where条件,且使用索引查找。
- 【强制】生产环境禁止使用
hint,如sql_no_cache,force index,ignore key,straight join等。因为hint是用来强制SQL按照某个执行计划来执行,但随着数据量变化我们无法保证自己当初的预判是正确的,因此我们要相信MySQL优化器! - 【强制】where条件里等号左右字段类型必须一致,否则无法利用索引。
- 【建议】
SELECT|UPDATE|DELETE|REPLACE要有WHERE子句,且WHERE子句的条件必需使用索引查找。 - 【强制】生产数据库中强烈不推荐大表上发生全表扫描,但对于100行以下的静态表可以全表扫描。查询数据量不要超过表行数的25%,否则不会利用索引。
- 【强制】WHERE 子句中禁止只使用全模糊的LIKE条件进行查找,必须有其他等值或范围查询条件,否则无法利用索引。
- 【建议】索引列不要使用函数或表达式,否则无法利用索引。如
where length(name)=\'Admin\'或where user_id 2=10023。 - 【建议】减少使用or语句,可将or语句优化为union,然后在各个where条件上建立索引。如
where a=1 or b=2优化为where a=1… union …where b=2, key(a),key(b)。 - 【建议】分页查询,当limit起点较高时,可先用过滤条件进行过滤。如
select a,b,c from t1 limit 10000,20;优化为:select a,b,c from t1 where id>10000 limit 20;。
2.2.2 多表连接
- 【强制】禁止跨db的join语句。因为这样可以减少模块间耦合,为数据库拆分奠定坚实基础。
- 【强制】禁止在业务的更新类SQL语句中使用join,比如
update t1 join t2…。 - 【建议】不建议使用子查询,建议将子查询SQL拆开结合程序多次查询,或使用join来代替子查询。
- 【建议】线上环境,多表join不要超过3个表。
- 【建议】多表连接查询推荐使用别名,且SELECT列表中要用别名引用字段,数据库.表格式,如
select a from db1.table1 alias1 where …。 - 【建议】在多表join中,尽量选取结果集较小的表作为驱动表,来join其他表。
2.2.3 事务
- 【建议】事务中
INSERT|UPDATE|DELETE|REPLACE语句操作的行数控制在2000以内,以及WHERE子句中IN列表的传参个数控制在500以内。 - 【建议】批量操作数据时,需要控制事务处理间隔时间,进行必要的sleep,一般建议值5-10秒。
- 【建议】对于有
auto_increment属性字段的表的插入操作,并发需要控制在200以内。 - 【强制】程序设计必须考虑“数据库事务隔离级别”带来的影响,包括脏读、不可重复读和幻读。线上建议事务隔离级别为
repeatable-read。 - 【建议】事务里包含SQL不超过5个(支付业务除外)。因为过长的事务会导致锁数据较久,MySQL内部缓存、连接消耗过多等雪崩问题。
- 【建议】事务里更新语句尽量基于主键或
unique key,如update … where id=XX; 否则会产生间隙锁,内部扩大锁定范围,导致系统性能下降,产生死锁。 - 【建议】尽量把一些典型外部调用移出事务,如调用webservice,访问文件存储等,从而避免事务过长。
- 【建议】对于MySQL主从延迟严格敏感的select语句,请开启事务强制访问主库。
2.2.4 排序和分组
- 【建议】减少使用
order by,和业务沟通能不排序就不排序,或将排序放到程序端去做。order by、group by、distinct这些语句较为耗费CPU,数据库的CPU资源是极其宝贵的。 - 【建议】
order by、group by、distinct这些SQL尽量利用索引直接检索出排序好的数据。如where a=1 order by可以利用key(a,b)。 - 【建议】包含了
order by、group by、distinct这些查询的语句,where条件过滤出来的结果集请保持在1000行以内,否则SQL会很慢。
2.2.5 线上禁止使用的SQL语句
- 【高危】禁用
update|delete t1 … where a=XX limit XX;这种带limit的更新语句。因为会导致主从不一致,导致数据错乱。建议加上order by PK。 - 【高危】禁止使用关联子查询,如
update t1 set … where name in(select name from user where…);效率极其低下。 - 【强制】禁用procedure、function、trigger、views、event、外键约束。因为他们消耗数据库资源,降低数据库实例可扩展性。推荐都在程序端实现。
- 【强制】禁用
insert into …on duplicate key update…在高并发环境下,会造成主从不一致。 - 【强制】禁止联表更新语句,如
update t1,t2 where t1.id=t2.id…。
MySQL存储过程
存储过程简介
SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
存储过程是可编程的函数,在数据库中创建并保存,可以由SQL语句和控制结构组成。当想要在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟,它允许控制数据的访问方式。
存储过程的优点:
(1).增强SQL语言的功能和灵活性:存储过程可以用控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
(2).标准组件式编程:存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
(3).较快的执行速度:如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
(4).减少网络流量:针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织进存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大减少网络流量并降低了网络负载。
(5).作为一种安全机制来充分利用:通过对执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
MySQL的存储过程
存储过程是数据库的一个重要的功能,MySQL 5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣。好在MySQL 5.0开始支持存储过程,这样即可以大大提高数据库的处理速度,同时也可以提高数据库编程的灵活性。
MySQL存储过程的创建
语法
CREATE PROCEDURE 过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 ...] 过程体
DELIMITER //
CREATE PROCEDURE myproc(OUT s int)
BEGIN
SELECT COUNT(*) INTO s FROM students;
END
//
DELIMITER ;
分隔符
MySQL默认以";"为分隔符,如果没有声明分割符,则编译器会把存储过程当成SQL语句进行处理,因此编译过程会报错,所以要事先用“DELIMITER //”声明当前段分隔符,让编译器把两个"//"之间的内容当做存储过程的代码,不会执行这些代码;“DELIMITER ;”的意为把分隔符还原。
参数
存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用","分割开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:
- IN参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
- OUT:该值可在存储过程内部被改变,并可返回
- INOUT:调用时指定,并且可被改变和返回
过程体
过程体的开始与结束使用BEGIN与END进行标识。
IN参数例子
DELIMITER //
CREATE PROCEDURE in_param(IN p_in int)
BEGIN
SELECT p_in;
SET p_in=2;
SELECT p_in;
END;
//
DELIMITER ;#调用
SET @p_in=1;
CALL in_param(@p_in);SELECT @p_in;执行结果:


以上可以看出,p_in虽然在存储过程中被修改,但并不影响@p_id的值OUT参数例子#存储过程OUT参数
DELIMITER //
CREATE PROCEDURE out_param(OUT p_out int)
BEGIN
SELECT p_out;
SET p_out=2;
SELECT p_out;
END;
//
DELIMITER ;
#调用
SET @p_out=1;
CALL out_param(@p_out);SELECT @p_out;执行结果:


INOUT参数例子#存储过程INOUT参数
DELIMITER //
CREATE PROCEDURE inout_param(INOUT p_inout int)
BEGIN
SELECT p_inout;
SET p_inout=2;
SELECT p_inout;
END;
//
DELIMITER ;
#调用
SET @p_inout=1;
CALL inout_param(@p_inout) ;
SELECT @p_inout;执行结果:


变量
语法:DECLARE 变量名1[,变量名2...] 数据类型 [默认值];
数据类型为MySQL的数据类型:
数值类型

日期和时间类型

字符串类型

变量赋值
语法:SET 变量名 = 变量值 [,变量名= 变量值 ...]
用户变量
用户变量一般以@开头
注意:滥用用户变量会导致程序难以理解及管理
#在MySQL客户端使用用户变量
SELECT \'Hello World\' into @x;
SELECT @x;SET @y=\'Goodbye Cruel World\';
SELECT @y;
SET @z=1 2 3;
SELECT @z;执行结果:


#在存储过程中使用用户变量
CREATE PROCEDURE GreetWorld() SELECT CONCAT(@greeting,\' World\');
SET @greeting=\'Hello\';
CALL GreetWorld();执行结果:
#在存储过程间传递全局范围的用户变量
CREATE PROCEDURE p1() SET @last_proc=\'p1\';
CREATE PROCEDURE p2() SELECT CONCAT(\'Last procedure was \',@last_proc);
CALL p1();
CALL p2();执行结果:
注释
MySQL存储过程可使用两种风格的注释:
- 双杠:--,该风格一般用于单行注释
- C风格: 一般用于多行注释
MySQL存储过程的调用
用call和你过程名以及一个括号,括号里面根据需要,加入参数,参数包括输入参数、输出参数、输入输出参数。
MySQL存储过程的查询
#查询存储过程
SELECT name FROM mysql.proc WHERE db=\'数据库名\';
SELECT routine_name FROM information_schema.routines WHERE routine_schema=\'数据库名\';
SHOW PROCEDURE STATUS WHERE db=\'数据库名\';#查看存储过程详细信息
SHOW CREATE PROCEDURE 数据库.存储过程名;MySQL存储过程的修改
ALTER PROCEDURE 更改用CREATE PROCEDURE 建立的预先指定的存储过程,其不会影响相关存储过程或存储功能。
ALTER {PROCEDURE | FUNCTION} sp_name [characteristic ...]
characteristic:
{ CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT \'string\' - sp_name参数表示存储过程或函数的名称;
- characteristic参数指定存储函数的特性。
- CONTAINS SQL表示子程序包含SQL语句,但不包含读或写数据的语句;
- NO SQL表示子程序中不包含SQL语句;
- READS SQL DATA表示子程序中包含读数据的语句;
- MODIFIES SQL DATA表示子程序中包含写数据的语句。
- SQL SECURITY { DEFINER | INVOKER }指明谁有权限来执行,DEFINER表示只有定义者自己才能够执行;INVOKER表示调用者可以执行。
- COMMENT \'string\'是注释信息。
实例:
#将读写权限改为MODIFIES SQL DATA,并指明调用者可以执行。
ALTER PROCEDURE num_from_employee
MODIFIES SQL DATA
SQL SECURITY INVOKER ;
#将读写权限改为READS SQL DATA,并加上注释信息\'FIND NAME\'。
ALTER PROCEDURE name_from_employee
READS SQL DATA
COMMENT \'FIND NAME\' ;MySQL存储过程的删除
DROP PROCEDURE [过程1[,过程2…]]从MySQL的表格中删除一个或多个存储过程。
MySQL存储过程的控制语句
变量作用域
内部变量在其作用域范围内享有更高的优先权,当执行到end时,内部变量消失,不再可见了,在存储
过程外再也找不到这个内部变量,但是可以通过out参数或者将其值指派给会话变量来保存其值。#变量作用域
DELIMITER //
CREATE PROCEDURE proc()
BEGIN
DECLARE x1 VARCHAR(5) DEFAULT \'outer\';
BEGIN
DECLARE x1 VARCHAR(5) DEFAULT \'inner\';
SELECT x1;
END;
SELECT x1;
END;
//
DELIMITER ;
#调用
CALL proc();执行结果:

条件语句
IF-THEN-ELSE语句
#条件语句IF-THEN-ELSE
DROP PROCEDURE IF EXISTS proc3;
DELIMITER //
CREATE PROCEDURE proc3(IN parameter int)
BEGIN
DECLARE var int;
SET var=parameter 1;
IF var=0 THEN
INSERT INTO t VALUES (17);
END IF ;
IF parameter=0 THEN
UPDATE t SET s1=s1 1;
ELSE
UPDATE t SET s1=s1 2;
END IF ;
END ;
//
DELIMITER ;CASE-WHEN-THEN-ELSE语句
#CASE-WHEN-THEN-ELSE语句
DELIMITER //
CREATE PROCEDURE proc4 (IN parameter INT)
BEGIN
DECLARE var INT;
SET var=parameter 1;
CASE var
WHEN 0 THEN
INSERT INTO t VALUES (17);
WHEN 1 THEN
INSERT INTO t VALUES (18);
ELSE
INSERT INTO t VALUES (19);
END CASE ;
END ;
//
DELIMITER ;循环语句WHILE-DO…END-WHILE
DELIMITER //
CREATE PROCEDURE proc5()
BEGIN
DECLARE var INT;
SET var=0;
WHILE var INSERT INTO t VALUES (var);
SET var=var 1;
END WHILE ;
END;
//
DELIMITER ;REPEAT...END REPEAT此语句的特点是执行操作后检查结果
DELIMITER //
CREATE PROCEDURE proc6 ()
BEGIN
DECLARE v INT;
SET v=0;
REPEAT
INSERT INTO t VALUES(v);
SET v=v 1;
UNTIL v>=5
END REPEAT;
END;
//
DELIMITER ;LOOP...END LOOP
DELIMITER //
CREATE PROCEDURE proc7 ()
BEGIN
DECLARE v INT;
SET v=0;
LOOP_LABLE:LOOP
INSERT INTO t VALUES(v);
SET v=v 1;
IF v >=5 THEN
LEAVE LOOP_LABLE;
END IF;
END LOOP;
END;
//
DELIMITER ;LABLES标号标号可以用在begin repeat while 或者loop 语句前,语句标号只能在合法的语句前面使用。可以跳出循环,使运行指令达到复合语句的最后一步。
ITERATE迭代
通过引用复合语句的标号,来从新开始复合语句
#ITERATE
DELIMITER //
CREATE PROCEDURE proc8()
BEGIN
DECLARE v INT;
SET v=0;
LOOP_LABLE:LOOP
IF v=3 THEN
SET v=v 1;
ITERATE LOOP_LABLE;
END IF;
INSERT INTO t VALUES(v);
SET v=v 1;
IF v>=5 THEN
LEAVE LOOP_LABLE;
END IF;
END LOOP;
END;
//
DELIMITER ;MySQL存储过程的基本函数字符串类CHARSET(str) //返回字串字符集
CONCAT (string2 [,... ]) //连接字串
INSTR (string ,substring ) //返回substring首次在string中出现的位置,不存在返回0
LCASE (string2 ) //转换成小写
LEFT (string2 ,length ) //从string2中的左边起取length个字符
LENGTH (string ) //string长度
LOAD_FILE (file_name ) //从文件读取内容
LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定开始位置
LPAD (string2 ,length ,pad ) //重复用pad加在string开头,直到字串长度为length
LTRIM (string2 ) //去除前端空格
REPEAT (string2 ,count ) //重复count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替换search_str
RPAD (string2 ,length ,pad) //在str后用pad补充,直到长度为length
RTRIM (string2 ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比较两字串大小,
SUBSTRING (str , position [,length ]) //从str的position开始,取length个字符,
注:mysql中处理字符串时,默认第一个字符下标为1,即参数position必须大于等于1SELECT SUBSTRING(\'abcd\',0,2);结果:
SELECT SUBSTRING(\'abcd\',1,2);结果:
TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字符
UCASE (string2 ) //转换成大写
RIGHT(string2,length) //取string2最后length个字符
SPACE(count) //生成count个空格数学类
ABS (number2 ) //绝对值
BIN (decimal_number ) //十进制转二进制
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //进制转换
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小数位数
HEX (DecimalNumber ) //转十六进制
注:HEX()中可传入字符串,则返回其ASC-11码,如HEX(\'DEF\')返回4142143
也可以传入十进制整数,返回其十六进制编码,如HEX(25)返回19
LEAST (number , number2 [,..]) //求最小值
MOD (numerator ,denominator ) //求余
POWER (number ,power ) //求指数
RAND([seed]) //随机数
ROUND (number [,decimals ]) //四舍五入,decimals为小数位数] 注:返回类型并非均为整数,如:#默认变为整型值SELECT ROUND(1.23);
SELECT ROUND(1.56);
#设定小数位数,返回浮点型数据
SELECT ROUND(1.567,2);
SIGN (number2 ) // 正数返回1,负数返回-1日期时间类ADDTIME (date2 ,time_interval ) //将time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //转换时区
CURRENT_DATE ( ) //当前日期
CURRENT_TIME ( ) //当前时间
CURRENT_TIMESTAMP ( ) //当前时间戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或时间
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式显示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上减去一个时间
DATEDIFF (date1 ,date2 ) //两个日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1为星期天
DAYOFYEAR (date ) //一年中的第几天
EXTRACT (interval_name FROM date ) //从date中提取日期的指定部分
MAKEDATE (year ,day ) //给出年及年中的第几天,生成日期串
MAKETIME (hour ,minute ,second ) //生成时间串
MONTHNAME (date ) //英文月份名
NOW ( ) //当前时间
SEC_TO_TIME (seconds ) //秒数转成时间
STR_TO_DATE (string ,format ) //字串转成时间,以format格式显示
TIMEDIFF (datetime1 ,datetime2 ) //两个时间差
TIME_TO_SEC (time ) //时间转秒数]
WEEK (date_time [,start_of_week ]) //第几周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第几天
HOUR(datetime) //小时
LAST_DAY(date) //date的月的最后日期
MICROSECOND(datetime) //微秒
MONTH(datetime) //月
MINUTE(datetime) //分返回符号,正负或0
SQRT(number2) //开平方
【项目管理】敏捷项目管理流程-Scrum框架最全总结
保护团队不受外界干扰,是团队的领导和推进者,负责提升 Scrum 团队的工作效率,控制 Scrum 中的“检视和适应”周期过程。与 Product Owner 一起将投资产出最大化,他确保所有的利益相关者都可以理解敏捷和尊重敏捷的理念。
Team——开发人员、测试人员、美工设计、DBA等全职能性团队
团队负责交付产品并对其质量负责,团队与所有提出产品需求的人一起工作,包括客户和最终用户,并共同创建 Product Backlog 。团队按照大家的共识来创建功能设计、测试 Backlog 条目交付产品。
Product Owner——产品负责人、产品经理、运营人员
从业务角度驱动项目,传播产品的明确愿景,并定义其主要特性。Product Owner 的主要职责是确保团队只开发对于组织最重要的 Backlog 条目,在 Sprint 中帮助团队完成自己的工作,不干扰团队成员,并迅速提供团队需要的所有信息。
User——最终用户、运营人员、系统使用人员
很多人都可能成为最终用户,比如市场部人员、真正的最终用户、最好的领域专家,也可能是因其专业知识而被雇佣的资讯顾问。最终用户会根据自己的业务知识定义产品,并告知团队自己的期望,提出请求。
Manager——管理层、投资人
管理层要为 Scrum 团队搭建良好的环境,以确保团队能够出色工作,必要的时候,他们也会与 Scrum Master 一起重新组织结构和指导原则。
Customer——客户、系统使用人员、运营人员
产品 Backlog 包括了所有需要交付的内容,其内容根据业务需求的价值顺序排列,每个 Backlog 的优先级是可以调整的,需求是可以增减的,因此产品 Backlog 将根据不断增长来持续驱动维护。
Sprint Backlog——Sprint 本意为“冲刺”,指迭代周期,长度通常是一至六周。
在 Sprint 开始前,定义本次 Sprint 要讨论的“Sprint Backlog”,从中产生本次 Sprint 要完成的 “已定 Product Backlog”。
已定 Product Backlog是 Sprint 计划会议的产物,它定义了团队所接受的工作量,在整个 Sprint 过程中它将保持不变。
User Story、Task——用户故事、任务
用 User Story 来描述 Sprint Backlog 里的项目,User Story 是从用户的角度对系统的某个功能模块所作的简短描述。一个 User Story 描述了项目中的一个小功能,以及这个功能完成之后将会产生什么效果,或者说能为客户创造什么价值。一个 User Story 的大小和复杂度应该以能在一个 Sprint 中完成为宜。如果 User Story 太大,可能会导致对它的开发横跨几个 Sprint,此时就应该将这个 User Story 分解。为了能够及时,高效地完成每个 Story,Scrum 团队会把每个 Story 分解成若干个 Task。每个Task 的时间最好不要超过8小时,保证在1个工作日内完成,如果 Task 的时间超过了8个小时,就说明Task的划分有问题,需要特别注意。
障碍 Backlog——问题列表,积压的待处理事务。
列举了所有团队内部和团队相关的和阻碍项目的进度的问题,Scrum Master 需要确保所有的障碍 Backlog 中的问题都已分配并可以得到解决。
•每次会议都要准时开始、准时结束。
•每次会议都采取开放形式,所有人都可以参加。
会前准备
•提前邀请所有必须参会的人,让他们有时间准备。
•发送带有会议目标和意图的会议纲要。
•预订会议所需的全部资源:房间、投影仪、挂图、主持设备,以及此会议需要的其他东西。
•会前24小时发送提醒。
•准备带有会议规则的挂图。
会议推进
•展开讨论时,会议的推进人必须在场。他不能参与到具体讨论中,但是他需要注意讨论进程,如果讨论参与者失去重点,他还要将讨论带回正规。
•推进人展示会议的目标和意图。
•有必要时,推进人可以商定由某个撰写会议记录。
•推进人可以记录团队的意见,或是教授团队如何自己记录文档;而且推进人可能会在挂图上进行记录,将对话可视化。
•推进人会对会议进行收尾,并进行非常简短的回顾。
会议输出
•使用手写或挂图说明来记录文档,给白板和挂图上的内容拍照。
•必须传达会议记录和大家对会议结果的明确共同认知。
让团队坐在一起!
•大家都懒的动,尽量让“产品负责人”和“全功能团队”都坐在一起!
•互相听到:所有人都可以彼此交谈,不必大声喊,不必离开座位。
•互相看到:所有人都可以看到彼此,都能看到任务板——不用非得近到可以看清楚内容,但至少可以看到个大概。
•隔离:如果你们整个团队突然站起来,自发形成一个激烈的设计讨论,团队外的任何人都不会被打扰到,反之亦然。
团队建设
•Scrum 团队最佳人数控制在“5~9”人。
•全职能性团队:开发组(后台开发、前端开发、测试人员——3~8人)、Scrum Master(项目经理)、产品负责人
•兼职团队成员:美工、DBA、运维
每日立会(Daily Standup Meeting)——建议下班前开始
会议目的
•团队在会议中作计划,协调其每日活动,还可以报告和讨论遇到的障碍。
•任务板能够帮助团队聚焦于每日活动之上,要在这个时候更新任务板和燃尽图。
构成部分
•任务板、即时贴、马克笔
•提示:ScrumMaster 不要站在团队前面或是任务板旁边,不要营造类似于师生教学的气氛。
基本要求
•成员:团队、Scrum Master
•无法出席的团队成员要由同伴代表。
•持续时间/举办地点:每天15分钟,同样时间,同样地点。
•提示:团队成员在聆听他人发言时,都应该想这个问题:“我该怎么帮他做得更快?”
会议输出
•团队彼此明确知道各自的工作,最新的工作进度图。
•得到最新的“障碍 Backlog”
•得到最新的“Sprint Backlog”
会议过程
•团队聚在故事板旁边,可以围成环形。
•从左边第一个开始,向团队伙伴说明他到现在完成的工作。
•然后该成员将任务板上的任务放到正确的列中。
•如果可以的话,该成员可以选取新的任务,交将其放入“进行中工作”列。
•如果该成员遇到问题或障碍,就要将其报告给 Scrum Master。
•每个团队成员重复步骤2到步骤5。
每个人三个问题:
•上次会议时的任务哪些已经完成?:把任务从“正在处理”状态转为“已完成”状态。——今天完成了什么?
•下次会议之前,你计划完成什么任务?:如果任务状态为“待处理”,转为“正在处理”状态。如果任务不在 Sprint Backlog 上,则添加这个任务。如果任务不能在一天成,把这任务细分成多个任务。如果任务可以在一天内完成,把任务状态设为“正在处理”。如果任务状态已经是“正在 处理”,询问是否存在阻碍任务完成得问题。——明天做什么?
•有什么问题阻碍了你的开发?:如果有阻碍你的开发进度的问题,把该障碍加入到障碍 Backlog中。——今天遇到了什么问题?
注意事项
•不要迟到
•不要超出限制时间
•不要讨论技术问题
•不要转变会议话题
•不要在没有准备的情况下参加
•Scrum Master 不要替团队成员移动任务卡片,不要替团队更新燃尽图。
•Scrum Master 不要提出问题,团队成员不要向 Scrum Master 或管理层人员报告。
•如果不能出席会议,需要通知团队,并找一名代表参加。
•任务板只能由团队维护,使用不同颜色的“即时贴”来区分开发人员,或者在“即时贴”写上接受任务的姓名。
•尽量使用大白板,也可以使用软件。
任务板有4列:
•选择好的 Product Backlog:按照优先级,将团队在当前 Sprint 中要着手的 Product Backlog 条目或是故事放在该列中。
•如果燃尽图一直是上升状态,或当 Sprint 进行一段时间之后,Sprint 燃尽图上的Y值仍然与 Sprint 刚开始时相差无几,就说明这个 Sprint 中的 Story 过多,要拿掉一些 Story 以保证这个 Sprint 能顺利完成。 如果Sprint 燃尽图下降得很快,例如 Sprint 刚过半时Y值已经接近0了,则说明这个 Sprint 分配的任务太少,还要多加一些任务进来。在 Sprint 计划会议上,如果团队对即将要做的任务理解和认识不充分,就很可能导致这两种情况的出现。(锻炼团队人员的自我估算时间)
•燃尽图要便于团队更新,没必要让它看起来很炫,也不要过于复杂,难以维护。
Release 燃尽图:记录整个Scurm项目的进度,它的横轴表示这个项目的所有Sprint, 纵轴表示各个Sprint开始前,尚未完成的工作,它的单位可以是个(Story 的数量),人天等。
•该会议的工作以分析为主,目的是要详细理解最终用户到底要什么,产品开发团队可以从该会议中详细了解最终用户的真实需要。在会议的结束,团队将会决定他们能够交付哪些东西。
•产品负责人在会前准备:条目化的需求(用户故事),优先级排序,最近1~2个迭代最希望看到的功能。会前准备至关重要,可帮助产品负责人理清头绪,不至于在迭代期内频繁提出变更、增加或删除故事。
基本要求
•迭代计划会在每个迭代第一天召开,目的是选择和估算本次迭代的工作项。
•只有团队成员才能决定团队在当前 Sprint 中能够领取多少个 Backlog 条目的工作。
构成部分:
•经过估算和排序的 Product Backlog。
•挂图、马克笔、剪刀、胶水、即时贴、白板、铅笔和蜡笔。
•假期计划表、重要人员的详细联系信息。
•参会成员:团队成员、Scrum Master、产品负责人
持续时间:在 Sprint 中,每周该会议占用时间为 60 分钟,在早上召开该会议,这样还有可能在同一天召开 Sprint 规划会议的第二部分。
会议输出
•选择好的 Product Backlog 条目。
•各个 Backlog 条目的需求。
•各个 Backlog 条目的用户验收测试。
会议过程
•从第一个 Product Backlog 条目(故事)开始。
•讨论该 Product Backlog 条目,以深入理解。
•分析、明确用户验收测试。
•找到非功能性需求(性能、稳定性...)
•找到验收条件。
•弄清楚需要“完成”到何种水平。
•获得 Backlog 条目各个方面的清晰了解。
•绘制出所需交付物的相关图表,包括流程图、UML图、手绘草图、屏幕 UI 设计等。
•回到步骤1,选取下一个 Backlog 条目。
流程检查:询问团队能否快速回答下列问题,只需要简要回答即可:“我们能在这个 Sprint 中完成第一个 Backlog 条目吗?”如果能得到肯定的回答,那么继续询问下一个 Backlog 条目,一直到已经分析完的最后一个 Backlog 条目。——接下来,休息一下。在休息后,对下一个 Backlog 条目展开上述流程。
结束流程:
•在 Sprint 规划会议第一部分结束前留出 20 分钟。
•再次提问——这次要更加严肃、正式:“你们能否完成第一个 Backlog 条目,...第二个,...?”
•如果团队认为他们不能再接受更多的 Backlog 条目,那就停下来。
•现在是非常重要的一步:送走 Product Owner,除了团队和 Scrum Master 之外的所有人,都得离开。
•当其他人都离开后,再询问团队:“说真的——你们相信自己可以完成这个列表?”
•希望团队现在能短暂讨论一下,看看他们到底认为自己能完成多少工作。
•将结果与 Product Owner 和最终用户沟通。
注意事项:不要改变 Backlog 条目大小,不要估算任务。
•该会议的工作以设计为主,产品开发团队可以为他们要实现的解决方案完成设计工作,在会议结束后,团队知道如何构建他们在当前 Sprint 中要开发的功能。
基本要求
•只有产品开发团队才能制定解决方案,架构师或其他团队之外的人只是受邀帮助团队。
构成部分:
•能够帮助团队在该 Sprint 中构建解决方案的人,比如厂商或是来自其他团队的人员。
•选择好的 Product Backlog 条目。
•挂图......
注意事项:不要估算任务,不要分配任务。
会议输出
•应用设计、架构设计图、相关图表
•确保团队知道应该如何完成任务!
会议过程
•从第一个 Backlog 条目开始。
•查看挂图,确定对于客户的需求理解正确。
•围绕该 Backlog 条目进行设计,并基于下列类似问题: •我们需要编写什么样的接口?
•我们需要创建什么样的架构?
•我们需要更新哪些表?
•我们需要更新或是编写哪些组件?
•......
持续时间:在 Sprint 规划会议第一部分完成后,召开该会议。可以将午餐作为两次会议的一个更长久的休息。但是要在同一天完成 Sprint 规划第一部分,在 Sprint 中,每周该会议占用时间为 60 分钟。
•要做好战略规划,你需要知道 Backlog 中各项的大小,这是版本规划的必要输入;如果想知道团队在一个 Sprint 中能够完成多少工作,这个数据也是必须的。
•团队成员可以从会议中知道项目接下来的阶段会发生哪些事情。
基本要求
•只有团队才能作估算,Product Owner(产品负责人)需要在场,以帮助判定某些用户故事能否拆分为更小的故事。
构成部分:
•Product Owner 根据业务价值排定 Product Backlog 各项顺序。
•需要参加的人员:Team、Product Owner、User、Scrum Master
注意事项:
•不要估算工作量大小——只有团队能这么做。
•Product Owner 不参与估算。
会议过程
•Prodcut Owner 展示她希望得到估算的 Product Backlog 条目。
•团队使用规划扑克来估算 Backlog 条目。
•如果某个 Backlog 条目过大,需要放到下一个或是后续的 Sprint 中,团队就会将该大 Backlog 条目划分为较小的几个 Backlog 条目,并对新的 Backlog 条目使用规划扑克进行估算。
•重新估算 Backlog 中当前没有完成、但是可能会在接下来三个 Sprint 中要完成的条目。
持续时间:该会议时间限制为不超过90分钟。如果 Sprint 持续时间长于一周,那么每个 Sprint 举行两次估算会议比较合适。
会议输出
•经过估算的 Product Backlog。
•更小的 Backlog 条目。
•每个人各自估算后独立出暗牌,听口令一起开牌。
•数值最大者与最小者PK,其他人旁听也可参考。
•讨论结束后重新出牌和开牌。
•重复上述过程,直到结果比较接近。
常见问题
1、为什么任务要分给组而不是个人?
答:因为怕出错了牌又说不出所以然,这样即使日后他不做这个功能,也对这个功能很了解。
2、为什么不让最后领任务的人自己估算?
答:因为他很可能因为不知道某代码可用、不知道某软件不行....而选择了错误的实现方法。
3、为什么不让师傅估算大家采纳,他不是最厉害吗?
答:师傅的想法常常是徒弟们理解不了的,比如为什么不留在女儿国而偏偏去西天取经之类的,共同估算就是让大家在思考中对照自己的实现方法和师傅差异的过程。
•Scrum 团队在会议中向最终用户展示工作成果,团队成员希望得到反馈,并以之创建或变更 Backlog 条目。
基本要求
•Sprint 复审会议允许所有的参与者尝试由团队展示的新功能。
构成部分
•有可能发布的产品增量,由团队展示。
会议输出
•来自最终用户的反馈。
•障碍 Backlog 的输入。
•团队 Backlog 的输入。
•来自团队的反馈为 Product Backlog 产生输入。
持续时间:90分钟,在 Sprint 结束时进行。
会议过程
•Product Owner 欢迎大家来参加 Sprint 复审会议。
•Product Owner 提醒大家关于本次 Sprint 的目的:Sprint 目标、Scrum 团队在本次 Sprint 中选定要开发的故事。
•产品开发团队展示新功能,并让最终用户尝试新功能。
•Scrum Master 推进会议进程。
•最终用户的反馈将会由 Product Owner 和/或 Scrum Master 记录在案。
注意事项:
•不要展示不可能发布的产品增量。
•Scrum Master 不要负责展示结果。
•团队不要针对 Product Owner 展示。
•该会议的对应隐喻:医疗诊断!其目的不是为了找到治愈方案,而是要发现哪些方面需要改进。
构成部分
•参与人员:团队成员、Scrum Master
基本要求
•从过去中学习,指导将来。
•改进团队的生产力。
注意事项
•不要让管理层人员参与会议。
•不要在团队之外讨论找到的东西。
会议输出
•障碍 Backlog 的输入。
•团队 Backlog 的输入。
持续时间:90分钟,在 Sprint 评审会议结束后几分钟开始。
会议过程
•准备一个写着“过去哪些做的不错?”的挂图。
•准备一个写着“哪些应该改进?”的挂图。
•绘制一条带有开始和结束日期的时间线。
•给每个团队成员发放一叠即时贴。
•开始回顾。
•做一个安全练习。
•收集事实:发放即时贴,用之构成一条时间线。每个团队成员(包括 Scrum Master)在每张即时贴上写上一个重要的事件。
•“过去哪些做的不错?”:采取收集事实同样的过程,不过这次要把即时贴放在准备好的挂图上。
•做一个分隔,以区分“过去哪些做的不错”和接下来要产出的东西。
•“哪些应该改进?”:像“过去哪些做的不错”那样进行。
•现在将即时贴分组:
•我们能做什么》团队 Backlog 的输入。
•哪些不在我们掌控之内?》障碍 Backlog 的输入。
•根据团队成员的意见对两个列表排序。
•将这两个列表作为下个 Sprint 的 Sprint 规划会议第一部分和 Sprint 规划会议第二部分的输入,并决定到时候要如何处理这些发现的信息。
Redis 数据类型详解适用场景场合
1. MySql+Memcached架构的问题
实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量的不断增加,和访问量的持续增长,我们遇到了很多问题:
1.MySQL需要不断进行拆库拆表,Memcached也需不断跟着扩容,扩容和维护工作占据大量开发时间。
2.Memcached与MySQL数据库数据一致性问题。
3.Memcached数据命中率低或down机,大量访问直接穿透到DB,MySQL无法支撑。
4.跨机房cache同步问题。
众多NoSQL百花齐放,如何选择
最近几年,业界不断涌现出很多各种各样的NoSQL产品,那么如何才能正确地使用好这些产品,最大化地发挥其长处,是我们需要深入研究和思考的问题,实际归根结底最重要的是了解这些产品的定位,并且了解到每款产品的tradeoffs,在实际应用中做到扬长避短,总体上这些NoSQL主要用于解决以下几种问题
1.少量数据存储,高速读写访问。此类产品通过数据全部in-momery 的方式来保证高速访问,同时提供数据落地的功能,实际这正是Redis最主要的适用场景。
2.海量数据存储,分布式系统支持,数据一致性保证,方便的集群节点添加/删除。
3.这方面最具代表性的是dynamo和bigtable 2篇论文所阐述的思路。前者是一个完全无中心的设计,节点之间通过gossip方式传递集群信息,数据保证最终一致性,后者是一个中心化的方案设计,通过类似一个分布式锁服务来保证强一致性,数据写入先写内存和redo log,然后定期compat归并到磁盘上,将随机写优化为顺序写,提高写入性能。
4.Schema free,auto-sharding等。比如目前常见的一些文档数据库都是支持schema-free的,直接存储json格式数据,并且支持auto-sharding等功能,比如mongodb。
面对这些不同类型的NoSQL产品,我们需要根据我们的业务场景选择最合适的产品。
Redis最适合所有数据in-momory的场景,虽然Redis也提供持久化功能,但实际更多的是一个disk-backed的功能,跟传统意义上的持久化有比较大的差别,那么可能大家就会有疑问,似乎Redis更像一个加强版的Memcached,那么何时使用Memcached,何时使用Redis呢?
如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点:
1 、Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2 、Redis支持数据的备份,即master-slave模式的数据备份。
3 、Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
2. Redis常用数据类型
Redis最为常用的数据类型主要有以下:
- String
- Hash
- List
- Set
- Sorted set
- pub/sub
- Transactions
在具体描述这几种数据类型之前,我们先通过一张图了解下Redis内部内存管理中是如何描述这些不同数据类型的:
首先Redis内部使用一个redisObject对象来表示所有的key和value,redisObject最主要的信息如上图所示:
type代表一个value对象具体是何种数据类型,
encoding是不同数据类型在redis内部的存储方式,
比如:type=string代表value存储的是一个普通字符串,那么对应的encoding可以是raw或者是int,如果是int则代表实际redis内部是按数值型类存储和表示这个字符串的,当然前提是这个字符串本身可以用数值表示,比如:"123" "456"这样的字符串。
这里需要特殊说明一下vm字段,只有打开了Redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的,该功能会在后面具体描述。通过上图我们可以发现Redis使用redisObject来表示所有的key/value数据是比较浪费内存的,当然这些内存管理成本的付出主要也是为了给Redis不同数据类型提供一个统一的管理接口,实际作者也提供了多种方法帮助我们尽量节省内存使用,我们随后会具体讨论。
3. 各种数据类型应用和实现方式
下面我们先来逐一的分析下这7种数据类型的使用和内部实现方式:
- String:
Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字.常用命令: set,get,decr,incr,mget 等。
应用场景:String是最常用的一种数据类型,普通的key/ value 存储都可以归为此类.即可以完全实现目前 Memcached 的功能,并且效率更高。还可以享受Redis的定时持久化,操作日志及 Replication等功能。除了提供与 Memcached 一样的get、set、incr、decr 等操作外,Redis还提供了下面一些操作:
-
- 获取字符串长度
- 往字符串append内容
- 设置和获取字符串的某一段内容
- 设置及获取字符串的某一位(bit)
- 批量设置一系列字符串的内容
实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。
- Hash
常用命令:hget,hset,hgetall 等。
应用场景:在Memcached中,我们经常将一些结构化的信息打包成HashMap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。
我们简单举个实例来描述下Hash的应用场景,比如我们要存储一个用户信息对象数据,包含以下信息:
用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储,主要有以下2种存储方式:
第一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。
第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称作为唯一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,但是用户ID为重复存储,如果存在大量这样的数据,内存浪费还是非常可观的。
那么Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口,如下图:
也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取都可以直接通过其内部Map的Key(Redis里称内部Map的key为field), 也就是通过 key(用户ID) + field(属性标签) 就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。
这里同时需要注意,Redis提供了接口(hgetall)可以直接取到全部的属性数据,但是如果内部Map的成员很多,那么涉及到遍历整个内部Map的操作,由于Redis单线程模型的缘故,这个遍历操作可能会比较耗时,而另其它客户端的请求完全不响应,这点需要格外注意。
实现方式:
上面已经说到Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现,这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。
- List
常用命令:lpush,rpush,lpop,rpop,lrange等。
应用场景:
Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现。
Lists 就是链表,相信略有数据结构知识的人都应该能理解其结构。使用Lists结构,我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,
可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作Lists中某一段的api,你可以直接查询,删除Lists中某一段的元素。实现方式:
Redis list的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。
- Set
常用命令:
sadd,spop,smembers,sunion 等。
应用场景:
Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。
Sets 集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
实现方式:
set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。
- Sorted Set
常用命令:
zadd,zrange,zrem,zcard等
使用场景:
Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。
另外还可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
实现方式:
Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。
- Pub/Sub
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。
- Transactions
谁说NoSQL都不支持事务,虽然Redis的Transactions提供的并不是严格的ACID的事务(比如一串用EXEC提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),但是这个Transactions还是提供了基本的命令打包执行的功能(在服务器不出问题的情况下,可以保证一连串的命令是顺序在一起执行的,中间有会有其它客户端命令插进来执行)。Redis还提供了一个Watch功能,你可以对一个key进行Watch,然后再执行Transactions,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。
4. Redis实际应用场景
Redis在很多方面与其他数据库解决方案不同:它使用内存提供主存储支持,而仅使用硬盘做持久性的存储;它的数据模型非常独特,用的是单线程。另一个大区别在于,你可以在开发环境中使用Redis的功能,但却不需要转到Redis。
转向Redis当然也是可取的,许多开发者从一开始就把Redis作为首选数据库;但设想如果你的开发环境已经搭建好,应用已经在上面运行了,那么更换数据库框架显然不那么容易。另外在一些需要大容量数据集的应用,Redis也并不适合,因为它的数据集不会超过系统可用的内存。所以如果你有大数据应用,而且主要是读取访问模式,那么Redis并不是正确的选择。
然而我喜欢Redis的一点就是你可以把它融入到你的系统中来,这就能够解决很多问题,比如那些你现有的数据库处理起来感到缓慢的任务。这些你就可以通过Redis来进行优化,或者为应用创建些新的功能。在本文中,我就想探讨一些怎样将Redis加入到现有的环境中,并利用它的原语命令等功能来解决 传统环境中碰到的一些常见问题。在这些例子中,Redis都不是作为首选数据库。
1、显示最新的项目列表
下面这个语句常用来显示最新项目,随着数据多了,查询毫无疑问会越来越慢。
- SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10
在Web应用中,“列出最新的回复”之类的查询非常普遍,这通常会带来可扩展性问题。这令人沮丧,因为项目本来就是按这个顺序被创建的,但要输出这个顺序却不得不进行排序操作。
类似的问题就可以用Redis来解决。比如说,我们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上我们有一个“显示全部”的链接,点击后就可以获得更多的评论。
我们假设数据库中的每条评论都有一个唯一的递增的ID字段。
我们可以使用分页来制作主页和评论页,使用Redis的模板,每次新评论发表时,我们会将它的ID添加到一个Redis列表:
- LPUSH latest.comments <ID>
我们将列表裁剪为指定长度,因此Redis只需要保存最新的5000条评论:
LTRIM latest.comments 0 5000
每次我们需要获取最新评论的项目范围时,我们调用一个函数来完成(使用伪代码):
- FUNCTION get_latest_comments(start, num_items):
- id_list = redis.lrange("latest.comments",start,start+num_items - 1)
- IF id_list.length < num_items
- id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
- END
- RETURN id_list
- END
这里我们做的很简单。在Redis中我们的最新ID使用了常驻缓存,这是一直更新的。但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库。
我们的系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。
2、删除与过滤
我们可以使用LREM来删除评论。如果删除操作非常少,另一个选择是直接跳过评论条目的入口,报告说该评论已经不存在。
有些时候你想要给不同的列表附加上不同的过滤器。如果过滤器的数量受到限制,你可以简单的为每个不同的过滤器使用不同的Redis列表。毕竟每个列表只有5000条项目,但Redis却能够使用非常少的内存来处理几百万条项目。
3、排行榜相关
另一个很普遍的需求是各种数据库的数据并非存储在内存中,因此在按得分排序以及实时更新这些几乎每秒钟都需要更新的功能上数据库的性能不够理想。
典型的比如那些在线游戏的排行榜,比如一个Facebook的游戏,根据得分你通常想要:
- 列出前100名高分选手
- 列出某用户当前的全球排名
这些操作对于Redis来说小菜一碟,即使你有几百万个用户,每分钟都会有几百万个新的得分。
模式是这样的,每次获得新得分时,我们用这样的代码:
ZADD leaderboard <score> <username>
你可能用userID来取代username,这取决于你是怎么设计的。
得到前100名高分用户很简单:ZREVRANGE leaderboard 0 99。
用户的全球排名也相似,只需要:ZRANK leaderboard <username>。
4、按照用户投票和时间排序
排行榜的一种常见变体模式就像Reddit或Hacker News用的那样,新闻按照类似下面的公式根据得分来排序:
score = points / time^alpha
因此用户的投票会相应的把新闻挖出来,但时间会按照一定的指数将新闻埋下去。下面是我们的模式,当然算法由你决定。
模式是这样的,开始时先观察那些可能是最新的项目,例如首页上的1000条新闻都是候选者,因此我们先忽视掉其他的,这实现起来很简单。
每次新的新闻贴上来后,我们将ID添加到列表中,使用LPUSH + LTRIM,确保只取出最新的1000条项目。
有一项后台任务获取这个列表,并且持续的计算这1000条新闻中每条新闻的最终得分。计算结果由ZADD命令按照新的顺序填充生成列表,老新闻则被清除。这里的关键思路是排序工作是由后台任务来完成的。
5、处理过期项目
另一种常用的项目排序是按照时间排序。我们使用unix时间作为得分即可。
模式如下:
- 每次有新项目添加到我们的非Redis数据库时,我们把它加入到排序集合中。这时我们用的是时间属性,current_time和time_to_live。
- 另一项后台任务使用ZRANGE…SCORES查询排序集合,取出最新的10个项目。如果发现unix时间已经过期,则在数据库中删除条目。
6、计数
Redis是一个很好的计数器,这要感谢INCRBY和其他相似命令。
我相信你曾许多次想要给数据库加上新的计数器,用来获取统计或显示新信息,但是最后却由于写入敏感而不得不放弃它们。
好了,现在使用Redis就不需要再担心了。有了原子递增(atomic increment),你可以放心的加上各种计数,用GETSET重置,或者是让它们过期。
例如这样操作:
INCR user:<id> EXPIRE
user:<id> 60
你可以计算出最近用户在页面间停顿不超过60秒的页面浏览量,当计数达到比如20时,就可以显示出某些条幅提示,或是其它你想显示的东西。
7、特定时间内的特定项目
另一项对于其他数据库很难,但Redis做起来却轻而易举的事就是统计在某段特点时间里有多少特定用户访问了某个特定资源。比如我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。
每次我获得一次新的页面浏览时我只需要这样做:
SADD page:day1:<page_id> <user_id>
当然你可能想用unix时间替换day1,比如time()-(time()%3600*24)等等。
想知道特定用户的数量吗?只需要使用SCARD page:day1:<page_id>。
需要测试某个特定用户是否访问了这个页面?SISMEMBER page:day1:<page_id>。
8、实时分析正在发生的情况,用于数据统计与防止垃圾邮件等
我们只做了几个例子,但如果你研究Redis的命令集,并且组合一下,就能获得大量的实时分析方法,有效而且非常省力。使用Redis原语命令,更容易实施垃圾邮件过滤系统或其他实时跟踪系统。
9、Pub/Sub
Redis的Pub/Sub非常非常简单,运行稳定并且快速。支持模式匹配,能够实时订阅与取消频道。
10、队列
你应该已经注意到像list push和list pop这样的Redis命令能够很方便的执行队列操作了,但能做的可不止这些:比如Redis还有list pop的变体命令,能够在列表为空时阻塞队列。
现代的互联网应用大量地使用了消息队列(Messaging)。消息队列不仅被用于系统内部组件之间的通信,同时也被用于系统跟其它服务之间的交互。消息队列的使用可以增加系统的可扩展性、灵活性和用户体验。非基于消息队列的系统,其运行速度取决于系统中最慢的组件的速度(注:短板效应)。而基于消息队列可以将系统中各组件解除耦合,这样系统就不再受最慢组件的束缚,各组件可以异步运行从而得以更快的速度完成各自的工作。
此外,当服务器处在高并发操作的时候,比如频繁地写入日志文件。可以利用消息队列实现异步处理。从而实现高性能的并发操作。
11、缓存
Redis的缓存部分值得写一篇新文章,我这里只是简单的说一下。Redis能够替代memcached,让你的缓存从只能存储数据变得能够更新数据,因此你不再需要每次都重新生成数据了。
Linux查看系统配置常用命令
一、linux CPU大小
cat /proc/cpuinfo |grep "model name" && cat /proc/cpuinfo |grep "physical id"
说明:Linux下可以在/proc/cpuinfo中看到每个cpu的详细信息。但是对于双核的cpu,在cpuinfo中会看到两个cpu。常常会让人误以为是两个单核的cpu。
其实应该通过Physical Processor ID来区分单核和双核。而Physical Processor ID可以从cpuinfo或者dmesg中找到. flags 如果有 ht 说明支持超线程技术 判断物理CPU的个数可以查看physical id 的值,相同则为
二、内存大小 cat /proc/meminfo |grep MemTotal
三、硬盘大小 fdisk -l |grep Disk
四、uname -a # 查看内核/操作系统/CPU信息的linux系统信息命令
五、head -n 1 /etc/issue # 查看操作系统版本,是数字1不是字母L
六、cat /proc/cpuinfo # 查看CPU信息的linux系统信息命令
七、hostname # 查看计算机名的linux系统信息命令
八、lspci -tv # 列出所有PCI设备
九、lsusb -tv # 列出所有USB设备的linux系统信息命令
十、lsmod # 列出加载的内核模块
十一、env # 查看环境变量资源
十二、free -m # 查看内存使用量和交换区使用量
十三、df -h # 查看各分区使用情况
十四、du -sh # 查看指定目录的大小
十五、grep MemTotal /proc/meminfo # 查看内存总量
十六、grep MemFree /proc/meminfo # 查看空闲内存量
十七、uptime # 查看系统运行时间、用户数、负载
十八、cat /proc/loadavg # 查看系统负载磁盘和分区
十九、mount | column -t # 查看挂接的分区状态
二十、fdisk -l # 查看所有分区
二十一、swapon -s # 查看所有交换分区
二十二、hdparm -i /dev/hda # 查看磁盘参数(仅适用于IDE设备)
二十三、dmesg | grep IDE # 查看启动时IDE设备检测状况网络
二十四、ifconfig # 查看所有网络接口的属性
二十五、iptables -L # 查看防火墙设置
二十六、route -n # 查看路由表
二十七、netstat -lntp # 查看所有监听端口
二十八、netstat -antp # 查看所有已经建立的连接
二十九、netstat -s # 查看网络统计信息进程
三十、ps -ef # 查看所有进程
三十一、top # 实时显示进程状态用户
三十二、w # 查看活动用户
三十三、id # 查看指定用户信息
三十四、last # 查看用户登录日志
三十五、cut -d: -f1 /etc/passwd # 查看系统所有用户
三十六、cut -d: -f1 /etc/group # 查看系统所有组
三十七、crontab -l # 查看当前用户的计划任务服务
三十七、chkconfig –list # 列出所有系统服务
三十八、chkconfig –list | grep on # 列出所有启动的系统服务程序
三十九、rpm -qa # 查看所有安装的软件包
四十、cat /proc/cpuinfo :查看CPU相关参数的linux系统命令
四十一、cat /proc/partitions :查看linux硬盘和分区信息的系统信息命令
四十二、cat /proc/meminfo :查看linux系统内存信息的linux系统命令
四十三、cat /proc/version :查看版本,类似uname -r
四十四、cat /proc/ioports :查看设备io端口
四十五、cat /proc/interrupts :查看中断
四十六、cat /proc/pci :查看pci设备的信息
四十七、cat /proc/swaps :查看所有swap分区的信息
Redis内存数据库操作命令详解
默认无权限控制:
远程服务连接:
$ redis-cli -h 127.0.0.1 -p 6379
windows下 :redis-cli.exe -h 127.0.0.1 -p 6379
redis 127.0.0.1:6379>
远程服务停止:
$ redis-cli -h 172.168.10.254 -p6379 shutdown
2) 有权限控制时(加上-a 密码):
redis-cli -h 127.0.0.1 -p 6379 -a 123456
除了在登录时通过 -a 参数制定密码外,还可以登录时不指定密码,而在执行操作前进行认证。

Redis默认端口号为127.0.0.1,端口号默认为:6379。
此处本机访问远程IP为132.1.114.44的计算机,则首先要在已经安装了Redis的远程计算机上打开其服务器,redis.server.exe
接下来在本机运行redis.cli.exe,也可以通过命令行实现:输入-h 远程计算机IP -p 6379即可连接:

OK了,接下来如果想用自己写的客户端什么的连接远程Redis数据库也只需要输入远程计算机的IP就可以了~
Redis系列-远程连接redis
用法:redis-cli [OPTIONS] [cmd [arg [arg ...]]]
-h <主机ip>,默认是127.0.0.1
-p <端口>,默认是6379
-a <密码>,如果redis加锁,需要传递密码
--help,显示帮助信息
通过对rendis-cli用法介绍,在101上连接103应该很简单:
[root@linuxidc001 ~]# redis-cli -h 192.168.1.103 -p 6379
redis 192.168.1.103:6379>
在101上对103设置个个string值 user.1.name=zhangsan
redis 192.168.1.103:6379> set user.1.name zhangsan
OK
看到ok,表明设置成功了。然后直接在103上登陆,看能不能获取到这个值。
redis 192.168.1.103:6379> keys *
redis 192.168.1.103:6379> select 1
1、连接操作相关的命令
- quit:关闭连接(connection)
- auth:简单密码认证
2、对value操作的命令
- exists(key):确认一个key是否存在
- del(key):删除一个key
- type(key):返回值的类型
- keys(pattern):返回满足给定pattern的所有key
- randomkey:随机返回key空间的一个key
- rename(oldname, newname):将key由oldname重命名为newname,若newname存在则删除newname表示的key
- dbsize:返回当前数据库中key的数目
- expire:设定一个key的活动时间(s)
- ttl:获得一个key的活动时间
- select(index):按索引查询
- move(key, dbindex):将当前数据库中的key转移到有dbindex索引的数据库
- flushdb:删除当前选择数据库中的所有key
- flushall:删除所有数据库中的所有key
3、对String操作的命令
- set(key, value):给数据库中名称为key的string赋予值value
- get(key):返回数据库中名称为key的string的value
- getset(key, value):给名称为key的string赋予上一次的value
- mget(key1, key2,…, key N):返回库中多个string(它们的名称为key1,key2…)的value
- setnx(key, value):如果不存在名称为key的string,则向库中添加string,名称为key,值为value
- setex(key, time, value):向库中添加string(名称为key,值为value)同时,设定过期时间time
- mset(key1, value1, key2, value2,…key N, value N):同时给多个string赋值,名称为key i的string赋值value i
- msetnx(key1, value1, key2, value2,…key N, value N):如果所有名称为key i的string都不存在,则向库中添加string,名称key i赋值为value i
- incr(key):名称为key的string增1操作
- incrby(key, integer):名称为key的string增加integer
- decr(key):名称为key的string减1操作
- decrby(key, integer):名称为key的string减少integer
- append(key, value):名称为key的string的值附加value
- substr(key, start, end):返回名称为key的string的value的子串
4、对List操作的命令
- rpush(key, value):在名称为key的list尾添加一个值为value的元素
- lpush(key, value):在名称为key的list头添加一个值为value的 元素
- llen(key):返回名称为key的list的长度
- lrange(key, start, end):返回名称为key的list中start至end之间的元素(下标从0开始,下同)
- ltrim(key, start, end):截取名称为key的list,保留start至end之间的元素
- lindex(key, index):返回名称为key的list中index位置的元素
- lset(key, index, value):给名称为key的list中index位置的元素赋值为value
- lrem(key, count, value):删除count个名称为key的list中值为value的元素。count为0,删除所有值为value的元素,count>0从 头至尾删除count个值为value的元素,count<0从尾到头删除|count|个值为value的元素。 lpop(key):返回并删除名称为key的list中的首元素 rpop(key):返回并删除名称为key的list中的尾元素 blpop(key1, key2,… key N, timeout):lpop命令的block版本。即当timeout为0时,若遇到名称为key i的list不存在或该list为空,则命令结束。如果timeout>0,则遇到上述情况时,等待timeout秒,如果问题没有解决,则对 keyi 1开始的list执行pop操作。
- brpop(key1, key2,… key N, timeout):rpop的block版本。参考上一命令。
- rpoplpush(srckey, dstkey):返回并删除名称为srckey的list的尾元素,并将该元素添加到名称为dstkey的list的头部
5、对Set操作的命令
- sadd(key, member):向名称为key的set中添加元素member
- srem(key, member) :删除名称为key的set中的元素member
- spop(key) :随机返回并删除名称为key的set中一个元素
- smove(srckey, dstkey, member) :将member元素从名称为srckey的集合移到名称为dstkey的集合
- scard(key) :返回名称为key的set的基数
- sismember(key, member) :测试member是否是名称为key的set的元素
- sinter(key1, key2,…key N) :求交集
- sinterstore(dstkey, key1, key2,…key N) :求交集并将交集保存到dstkey的集合
- sunion(key1, key2,…key N) :求并集
- sunionstore(dstkey, key1, key2,…key N) :求并集并将并集保存到dstkey的集合
- sdiff(key1, key2,…key N) :求差集
- sdiffstore(dstkey, key1, key2,…key N) :求差集并将差集保存到dstkey的集合
- smembers(key) :返回名称为key的set的所有元素
- srandmember(key) :随机返回名称为key的set的一个元素
6、对zset(sorted set)操作的命令
- zadd(key, score, member):向名称为key的zset中添加元素member,score用于排序。如果该元素已经存在,则根据score更新该元素的顺序。
- zrem(key, member) :删除名称为key的zset中的元素member
- zincrby(key, increment, member) :如果在名称为key的zset中已经存在元素member,则该元素的score增加increment;否则向集合中添加该元素,其score的值为increment
- zrank(key, member) :返回名称为key的zset(元素已按score从小到大排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”
- zrevrank(key, member) :返回名称为key的zset(元素已按score从大到小排序)中member元素的rank(即index,从0开始),若没有member元素,返回“nil”
- zrange(key, start, end):返回名称为key的zset(元素已按score从小到大排序)中的index从start到end的所有元素
- zrevrange(key, start, end):返回名称为key的zset(元素已按score从大到小排序)中的index从start到end的所有元素
- zrangebyscore(key, min, max):返回名称为key的zset中score >= min且score <= max的所有元素 zcard(key):返回名称为key的zset的基数 zscore(key, element):返回名称为key的zset中元素element的score zremrangebyrank(key, min, max):删除名称为key的zset中rank >= min且rank <= max的所有元素 zremrangebyscore(key, min, max) :删除名称为key的zset中score >= min且score <= max的所有元素
- zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX):对N个zset求并集和交集,并将最后的集合保存在dstkeyN中。对于集合中每一个元素的score,在进行 AGGREGATE运算前,都要乘以对于的WEIGHT参数。如果没有提供WEIGHT,默认为1。默认的AGGREGATE是SUM,即结果集合中元素 的score是所有集合对应元素进行SUM运算的值,而MIN和MAX是指,结果集合中元素的score是所有集合对应元素中最小值和最大值。
7、对Hash操作的命令
- hset(key, field, value):向名称为key的hash中添加元素field<—>value
- hget(key, field):返回名称为key的hash中field对应的value
- hmget(key, field1, …,field N):返回名称为key的hash中field i对应的value
- hmset(key, field1, value1,…,field N, value N):向名称为key的hash中添加元素field i<—>value i
- hincrby(key, field, integer):将名称为key的hash中field的value增加integer
- hexists(key, field):名称为key的hash中是否存在键为field的域
- hdel(key, field):删除名称为key的hash中键为field的域
- hlen(key):返回名称为key的hash中元素个数
- hkeys(key):返回名称为key的hash中所有键
- hvals(key):返回名称为key的hash中所有键对应的value
- hgetall(key):返回名称为key的hash中所有的键(field)及其对应的value
8、持久化
- save:将数据同步保存到磁盘
- bgsave:将数据异步保存到磁盘
- lastsave:返回上次成功将数据保存到磁盘的Unix时戳
- shundown:将数据同步保存到磁盘,然后关闭服务
9、远程服务控制
- info:提供服务器的信息和统计
- monitor:实时转储收到的请求
- slaveof:改变复制策略设置
- config:在运行时配置Redis服务器
史上最全Vue相关开源项目库汇总
目录
UI组件
- element ★13489 - 饿了么出品的Vue2的web UI工具套件
- Vux ★8133 - 基于Vue和WeUI的组件库
- iview ★6634 - 基于 Vuejs 的开源 UI 组件库
- mint-ui ★6253 - Vue 2的移动UI元素
- muse-ui ★3705 - 三端样式一致的响应式 UI 库
- vue-material ★3328 - 通过Vue Material和Vue 2建立精美的app应用
- vuetify ★2925 - 为移动而生的Vue JS 2组件框架
- Keen-UI ★2749 - 轻量级的基本UI组件合集
- vonic ★1913 - 快速构建移动端单页应用
- vue-multiselect ★1539 - Vue.js选择框解决方案
- eme ★1529 - 优雅的Markdown编辑器
- vueAdmin ★1455 - 基于vuejs2和element的简单的管理员模板
- bootstrap-vue ★1267 - 应用于Vuejs2的Twitter的Bootstrap 4组件
- Vue.Draggable ★1191 - 实现拖放和视图模型数组同步
- eagle.js ★1128 - hacker的幻灯片演示框架
- vue-awesome-swiper ★1012 - vue.js触摸滑动组件
- vue-table ★1009 - 简化数据表格
- vue-chat ★859 - vuejs和vuex及webpack的聊天示例
- vue-blu ★850 - 帮助你轻松创建web应用
- vue-recyclerview ★849 - 管理大列表的vue-recyclerview
- VueCircleMenu ★838 - 漂亮的vue圆环菜单
- vue-infinite-scroll ★779 - VueJS的无限滚动指令
- buefy ★755 - 响应式UI组件轻量级库
- vue-beauty ★749 - 由vue和ant design创建的优美UI组件
- vue-waterfall ★737 - Vue.js的瀑布布局组件
- radon-ui ★715 - 快速开发产品的Vue组件库
- vue-loop ★701 - 无限的内容循环
- vue-chartjs ★694 - vue中的Chartjs的封装
- vue-carbon ★684 - 基于 vue 开发MD风格的移动端
- vue-syntax-highlight ★655 - Sublime Text语法高亮
- vue-echarts ★649 - VueJS的ECharts组件
- vue-quill-editor ★615 - 基于Quill适用于Vue2的富文本编辑器
- vue-amap ★571 - 基于Vue 2和高德地图的地图组件
- vue-calendar ★536 - 日期选择插件
- vue-infinite-loading ★501 - VueJS的无限滚动插件
- vue-swipe ★481 - VueJS触摸滑块
- vue-music-player ★451 - Vuejs写一个音乐播放器
- vue-scroller ★444 - Vonic UI的功能性组件
- vue-datepicker ★436 - 日历和日期选择组件
- vue-core-image-upload ★393 - 轻量级的vue上传插件
- vue-progressbar ★379 - vue轻量级进度条
- Gokotta ★375 - 简单的音乐播放器
- vue-sortable ★373 - 轻松添加拖拽排序
- vue-picture-input ★352 - 移动友好的图片文件输入组件
- vue-echarts-v3 ★351 - VueJS组件封装
- markcook ★343 - 好看的markdown编辑器
- vue-video-player ★336 - VueJS视频及直播播放器
- vue-google-maps ★334 - 带有双向数据绑定Google地图组件
- vue-trend ★332 - 简单优雅的星光线条
- vuejs-datepicker ★314 - vue日期选择器组件
- vue-fullcalendar ★313 - 基于vue.js的全日历组件
- vue-html5-editor ★303 - html5所见即所得编辑器
- vue-upload-component ★298 - Vuejs文件上传组件
- DataVisualization ★298 - 数据可视化
- vue-tables-2 ★291 - 显示数据的bootstrap样式网格
- VueStar ★270 - 带星星动画的vue点赞按钮
- vue-data-tables ★266 - VueJS2数据表格
- vue-paginate ★261 - 分页数据的简约VueJS插件
- vue-ydui ★247 - 基于Vue2的移动端和微信UI
- vue-mugen-scroll ★239 - 无限滚动组件
- vue-virtual-scroller ★238 - 带任意数目数据的顺畅的滚动
- vue2-calendar ★236 - 支持lunar和日期事件的日期选择器
- vue-dropzone ★233 - 用于文件上传的Vue组件
- vue2-douban-market ★233 - 仿豆瓣市集webapp项目
- vue-js-modal ★228 - 移动友好的Vuejs2的modal
- vue-slider ★224 - vue 滑动组件
- vue-datetime-picker ★224 - 日期时间选择控件
- rubik ★217 - 基于Vuejs2的开源 UI 组件库
- vue-datasource ★210 - 创建VueJS动态表格
- vue-image-crop-upload ★205 - vue图片剪裁上传组件
- Vueditor ★204 - 所见即所得的编辑器
- mint-loadmore ★203 - VueJS的双向下拉刷新组件
- vue-slider-component ★202 - 在vue1和vue2中使用滑块
- vue-chat ★200 - Vue全家桶+Socket.io+Express/Koa2打造一个智能聊天室
- mavonEditor ★179 - 基于Vue的markdown编辑器
- vue-carousel-3d ★173 - VueJS的3D轮播组件
- vue-baidu-map ★170 - 基于 Vue 2的百度地图组件库
- sweet-modal-vue ★170 - 精美的点击提示对话框
- vue-particles ★168 - 粒子背景的vue组件
- vue-swiper ★167 - 易于使用的滑块组件
- vue-simplemde ★166 - VueJS的Markdown编辑器组件
- vue-slide ★161 - vue轻量级滑动组件
- vue-dragula ★157 - 使拖放变得简单
- vue-drag-and-drop-list ★156 - 创建排序列表的Vue指令
- vue2-editor ★155 - HTML编辑器
- vue-charts ★152 - 轻松渲染一个图表
- vue-data-grid ★151 - VueJS复杂桌面交互示例
- vuwe ★150 - 基于微信WeUI所开发的专用于Vue2的组件库
- vue-progressive-image ★148 - Vue的渐进图像加载插件
- vue-msgbox ★148 - vuejs的消息框
- vue-lazyload-img ★147 - 移动优化的vue图片懒加载插件
- vue-dragging ★146 - 使元素可以拖拽
- vue-instant ★143 - 轻松创建自动提示的自定义搜索控件
- vue-social-sharing ★142 - 社交分享组件
- vue-images ★139 - 显示一组图片的lightbox组件
- vue-impression ★134 - 移动Vuejs2 UI元素
- vue-mdEditor ★131 - 基于VUE的markdown文本编辑器
- vue-typer ★130 - 模拟用户输入选择和删除文本的Vue组件
- vue-highcharts ★130 - HighCharts组件
- vue-tooltip ★129 - 带绑定信息提示的提示工具
- vue-svgicon ★127 - 创建svg图标组件的工具
- wdui ★124 - 基于Vue2的UI组件库
- vue2-loading-bar ★118 - 最简单的仿Youtube加载条视图
- vue-tabs-component ★116 - 渲染tabs的Vue组件
- MagicMusic ★113 - 不一样的音乐
- vue-region-picker ★111 - 选择中国的省份市和地区
- vue-datatable ★102 - 使用Vuejs创建的DataTableView
- vue-loading ★102 - 元素中加载block的Vue指令
- vodal ★99 - 动画的vue模态
- vue-img-inputer ★97 - 基于Vue2的图片输入框
- vue-video ★96 - Vue.js的HTML5视频播放器
- vue-touch-ripple ★95 - vuejs的触摸ripple组件
- vue-event-calendar ★91 - 简单小巧的事件日历组件
- v-bar ★91 - 虚拟响应跨浏览器滚动条
- vue2-timepicker ★84 - 下拉时间选择器
- vuejs-paginate ★80 - 分页VueJS组件
- vue-toast-mobile ★79 - VueJS的toast插件
- vue-datepicker ★78 - 漂亮的Vue日期选择器组件
- vue-easy-slider ★77 - Vue 2.x的滑块组件
- vue-float-label ★76 - VueJS浮动标签模式
- vue-scrollbar ★76 - 最简单的滚动区域组件
- vant ★74 - 有赞出品的Vue2.0移动UI
- vue-json-tree-view ★74 - Vue的JSON树视图
- vue-slick ★73 - 实现流畅轮播框的vue组件
- vue-keynote ★73 - 实现声明性代码幻灯片
- vue-google-signin-button ★73 - 导入谷歌登录按钮
- vue-rate ★68 - Vue评分组件
- awesome-mask ★67 - 拥有独一无二mask的表单
- vue-radial-progress ★65 - Vue.js放射性进度条组件
- vue-quill ★65 - vue组件构建quill编辑器
- vue-date-picker ★63 - VueJS日期选择器组件
- coffeebreak ★62 - 实时编辑CSS组件工具
- vue-good-wizard ★61 - VueJS 2.x wizard plugin
- vue-loading ★60 - 使用SVG加载
- datepicker ★59 - 基于flatpickr的时间选择组件
- vue-placeholders ★58 - 处理占位符图片和乱码
- we-vue ★55 - Vue2及weui1开发的组件
- vue-fullcalendar ★55 - vue FullCalendar封装
- vue-chartkick ★53 - VueJS一行代码实现优美图表
- cxlt-vue2-toastr ★52 - 弹出提示的Vue2组件
- vue-formly ★51 - VueJS的JS表单
- vue2-autocomplete ★51 - vue2的自动完成组件
- vue-morris ★50 - Vuejs组件封装Morrisjs库
- veui ★50 - VueJS百度企业UI
- vue-components ★49 - 移动端UI组件库
- vue-star-rating ★49 - 简单高度自定义的星星评级组件
- vue-tagsinput ★48 - 基于VueJS的标签组件
- vue-tabs ★47 - 多tab页轻型框架
- vue-popup-mixin ★47 - 用于管理弹出框的遮盖层
- vue-ripple-directive ★45 - 使用Vue指令的Material波纹效果
- vue-cropper ★42 - 一个简单的vue 的图片裁剪插件
- vue-ztree ★41 - 用 vue 写的树层级组件
- vue-touch-keyboard ★41 - VueJS虚拟键盘组件
- cubeex ★40 - 包含一套完整的移动UI
- vue-chart ★40 - 强大的高速的vue图表解析
- vue-music-master ★40 - vue手机端网页音乐播放器
- vue-bootstrap-table ★39 - 可排序可检索的表格
- vue-emoji ★39 - 好用的emoji插件
- handsontable ★39 - 网页表格组件
- vue-form-2 ★37 - 全面的HTML表单管理的解决方案
- vue-area ★37 - 省市区三级联动插件
- vue-side-nav ★37 - 响应式的侧边导航
- vue-image-scroll ★36 - 仿网易云音乐的vue图片滚动插件
- vue-pull-to-refresh ★35 - Vue2的上拉下拉
- mint-indicator ★35 - VueJS移动加载指示器插件
- vue-image-clip ★34 - 基于vue的图像剪辑组件
- vue-material-design ★34 - Vue MD风格组件
- vue-simple-upload ★31 - 简单的VueJS上传组件
- chartjs ★29 - Vue Bulma的chartjs组件
- vue-lazy-background-images ★29 - 懒加载背景组件的Vue组件
- vue-ripple ★29 - 制作谷歌MD风格涟漪效果的Vue组件
- vue-scroll ★27 - vue滚动
- laravel-vue-pagination ★26 - VueJS分页组件
- vue-datepicker-simple ★26 - 基于vue的日期选择器
- vue-m-carousel ★26 - vue 移动端轮播组件
- vue-parallax ★23 - 整洁的视觉效果
- vue-img-loader ★22 - 图片加载UI组件
- vue-tree ★22 - vue树视图组件
- vue-verify-pop ★22 - 带气泡提示的vue校验插件
- vue-waves ★22 - waves的VueJS版本
- vue-smoothscroll ★20 - smoothscroll的VueJS版本
- vue-city ★19 - 城市选择器
- vue-laypage ★17 - 简单的VueJS分页组件
- vue-typewriter ★15 - vue组件类型
- vue-ios-alertview ★14 - iOS7+ 风格的alertview服务
- vue-cmap ★14 - Vue China map可视化组件
- paco-ui-vue ★12 - PACOUI的vue组件
- vue-cascading-address ★9 - vue地区选择器
- dd-vue-component ★7 - 订单来了的公共组件库
- vue-button ★5 - Vue按钮组件
开发框架
- vue.js ★56380 - 流行的轻量高效的前端组件化方案
- vue-admin ★4612 - Vue管理面板框架
- quasar ★2353 - 响应式网站和混合移动应用程序
- electron-vue ★2085 - Electron及VueJS快速启动样板
- vue-element-admin ★1986 - vue2管理系统模板
- vuepack ★1618 - 现代VueJS启动器
- N3-components ★656 - 快速构建页面和应用
- VueThink ★373 - 前后端分离框架
- vue-2.0-boilerplate ★358 - Vue2单页应用样板
- vue-spa-template ★344 - 前后端分离后的单页应用开发
- Framework7-Vue ★283 - VueJS与Framework7结合
- vue-bulma ★215 - 轻量级高性能MVVM Admin UI框架
- vuetiful ★189 - 创建业务及管理应用程序
- vue-stack-2.0 ★155 - Vue2项目样板
- vue2-admin-lte ★154 - vue2版本的adminLTE
- jspangAdmin ★140 - 基于Vue2的后台管理系统
- vue-fullstack ★140 - 实时的用户友好的后台系统
- vue-paper-dashboard ★120 - Vue的Tim Paper 仪表盘
- vue-webgulp ★113 - 仿VueJS Vue loader示例
- vue-element-starter ★83 - vue启动页
- vuemin ★17 - 基于Vue的企业级前端开发框架
- vue-team-template ★12 - 一种构建vue项目的选择方案
实用库
- vuex ★8043 - 专为 Vue.js 应用程序开发的状态管理模式
- vue-loader ★1847 - Vue.js 针对Webpack的组件装载插件
- vue-validator ★1807 - vue的验证器插件
- vue-lazyload ★1224 - 用于懒加载的Vue模块
- vuelidate ★1075 - 简单轻量级的基于模块的Vue.js验证
- vue-i18n ★1053 - VueJS的多语言切换插件
- qingcheng ★736 - qingcheng主题
- Vue-Socketio ★533 - VueJS的socketio实现
- vue-awesome ★532 - VueJS字体Awesome组件
- vue-desktop ★496 - 创建管理面板网站的UI库
- vue-axios ★491 - 将axios整合到VueJS的封装
- vue-meta ★467 - 管理app的meta信息
- vue-head ★396 - head标签的meta信息操作
- meteor-vue-component ★382 - vue和meteor整合
- avoriaz ★338 - VueJS测试实用工具库
- portal-vue ★239 - 在组件外部渲染DOM
- vue-flatpickr ★228 - 封装Flatpickr的Vue组件
- vue-timeago ★195 - VueJS的时间前组件
- blessed-vue ★181 - 编写命令行UI的VueJS运行时
- vue-unit ★179 - 创建单元测试组件
- vue-authenticate ★177 - 简单的VueJS身份认证库
- vue-scrollTo ★174 - 滚动到元素的VueJS指令
- vue-svg-icon ★157 - vue2的可变彩色svg图标方案
- vue-focus ★148 - 可重用VueJS组件的焦点指令
- meteor-vue ★134 - VueJS和Meteor的桥接
- element-admin ★130 - 支持 vuecli 的 Element UI 的后台模板
- vuep ★118 - 用实时编辑和预览来渲染Vue组件
- vuet ★116 - 一个跨页面、跨组件的状态管理插件
- vue-bootstrap-modal ★112 - vue的Bootstrap样式组件
- vue-animate ★106 - 跨浏览器CSS3动画库
- vue-property-decorator ★104 - VueJS和属性Decorator
- vue-aplayer ★100 - 便于配置的音乐播放器vue2组件
- vue-password-strength-meter ★97 - 交互式密码强度计
- vue-websocket ★91 - VueJS的Websocket插件
- vue-local-storage ★88 - 具有类型支持的Vuejs本地储存插件
- vue-recyclist ★88 - vuejs无限滚动列表
- vue-lazy-render ★87 - 用于Vue组件的延迟渲染
- vue-qart ★86 - 用于qartjs的Vue2指令
- vue-framework7 ★85 - 结合VueJS使用的Framework7组件
- vue-cordova ★85 - Cordova的VueJS插件
- http-vue-loader ★84 - 从html及js环境加载vue文件
- vue-parallax ★84 - 快速60fps视差滚动效果组件
- vue-clipboard ★84 - VueJS的剪贴板
- vue-kindergarten ★83 - 将kindergarten集成到VueJS应用
- vue-events ★83 - 简化事件的VueJS插件
- vue-notifications ★80 - 非阻塞通知库
- vue-online ★77 - reactive的在线和离线组件
- vue-shortkey ★74 - 应用于Vue.js的Vue-ShortKey 插件
- vue-bus ★71 - VueJS的事件总线
- vuex-i18n ★71 - 定位插件
- uiv ★70 - Vue实现的Bootstrap组件
- vue-router-transition ★69 - 页面过渡插件
- vue-gesture ★69 - VueJS的手势事件插件
- vue-clip ★67 - 简约的破解文件上传器
- vue-electron ★66 - 将选择的API封装到Vue对象中的插件
- cleave ★64 - 基于cleave.js的Cleave组件
- vuemit ★63 - 处理VueJS事件
- vue-worker ★56 - 使用webworkers的Vue插件
- vue-acl ★54 - VueJS访问控制列表插件
- vue-ts-loader ★54 - 在Vue装载机检查脚本
- Vue.resize ★51 - 检测HTML调整大小事件的vue指令
- vuedeux ★50 - 轻量级开源实用用层
- vue-ls ★49 - 适配Vuecontext中LocalStorage的Vue插件
- lazy-vue ★48 - 懒加载图片
- vue-pagination-2 ★46 - 简单通用的分页组件
- v-media-query ★44 - vue中添加用于配合媒体查询的方法
- vue-observe-visibility ★42 - 当元素在页面上可见或隐藏时检测
- vue-lazy-component ★38 - 懒加载组件或者元素的Vue指令
- vue-reactive-storage ★37 - vue插件的Reactive层
- vue-helmet ★37 - HTML标题管理器
- voir ★35 - 保持mutation与视图组件的分离
- vuex-shared-mutations ★34 - 分享某种Vuex mutations
- vue-drag-zone ★28 - 适用于Vue2的dom拖动组件
- vue-eslint-parser ★27 - ESLint自定义解析
- modal ★26 - Vue Bulma的modal组件
- vue-plan ★25 - Vuex-状态管理
- vue-file-base64 ★22 - 将文件转换为Base64的vue组件
- vue-methods-promise ★21 - 使vue方法支持promise
- Vue.ImagesLoaded ★20 - 检测图片加载的VueJS指令
- Famous-Vue ★16 - Famous库的vue组件
- leo-vue-validator ★15 - 异步的表单验证组件
- vue-titlecase ★13 - 用于字符串titlecased的VueJS过滤器
- Vue-Easy-Validator ★12 - 简单的表单验证
- vue-zoombox ★12 - 一个高级zoombox
- vue-truncate-filter ★10 - 截断字符串的VueJS过滤器
- vue-router-storage ★9 - vue历史路由持久化的解决方案
- vue-input-autosize ★9 - 基于内容自动调整文本输入的大小
- vue-data-validator ★4 - Vuejs2的数据验证插件
- vue-lazyloadImg ★4 - 图片懒加载插件
服务端
- nuxt.js ★4564 - 用于服务器渲染Vue app的最小化框架
- unvue ★310 - 使用简单的通用VueJS应用
- express-vue ★302 - 简单的使用服务器端渲染vue.js
- vue-ssr ★92 - 非常简单的VueJS服务器端渲染模板
- doubanMovie-SSR ★85 - Vue豆瓣电影服务端渲染
- vue-ssr ★80 - 结合Express使用Vue2服务端渲染
- vue-easy-renderer ★44 - Nodejs服务端渲染
辅助工具
- vue-play ★641 - 展示Vue组件的最小化框架
- DejaVue ★635 - Vuejs可视化及压力测试
- vscode-VueHelper ★228 - 目前vscode最好的vue代码提示插件
- vue-generate-component ★56 - 轻松生成Vue js组件的CLI工具
- vue-multipage-cli ★40 - 简单的多页CLI
- VuejsStarterKit ★29 - vuejs starter套件
应用实例
- koel ★7773 - 基于网络的个人音频流媒体服务
- pagekit ★4225 - 轻量级的CMS建站系统
- vue-manage-system ★2057 - 后台管理系统解决方案
- vuedo ★1265 - 博客平台
- jackblog-vue ★1120 - 个人博客系统
- PJ Blog ★1018 - 开源博客
- vue-cnode ★787 - 重写vue版cnode社区
- vms ★629 - vuejs2管理系统
- CMS-of-Blog ★541 - 博客内容管理器
- goldfish ★518 - 用于HashiCorp Vault的Admin UI
- rss-reader ★368 - 简单的rss阅读器
- vue-ghpages-blog ★254 - 依赖GitHub Pages无需本地生成的静态博客
- vue-blog ★143 - 使用Vue2.0 和Vuex的vue-blog
- swoole-vue-webim ★137 - Web版的聊天应用
- tomato5 ★134 - 实时的协作工具
- Loopa-News ★133 - 开源社会新闻应用
- vue2-management-platform ★74 - vue2.0+ elementUI 后台管理平台
- vue-dashing-js ★70 - nuvo-dashing-js的fork
- fewords ★63 - 功能极其简单的笔记本
- adminify ★46 - 一个基于Vuetify material的Admin面板
Demo示例
- vue2-elm ★8036 - 重写饿了么webapp
- Vue-cnodejs ★2491 - 基于vue重写Cnodejs.org的webapp
- NeteaseCloudWebApp ★1549 - 高仿网易云音乐的webapp
- vue2-happyfri ★1535 - vue2及vuex的入门练习项目
- vue-zhihu-daily ★1010 - 知乎日报 with Vuejs
- vue2-demo ★994 - 从零构建vue2 + vue-router + vuex 开发环境
- vue-wechat ★939 - vue.js开发微信app界面
- eleme ★882 - 高仿饿了么app商家详情
- vue-demo ★755 - vue简易留言板
- bilibili-vue ★694 - 全栈式开发bilibili首页
- spa-starter-kit ★646 - 单页应用启动套件
- VueDemo_Sell_Eleme ★636 - Vue2高仿饿了么外卖平台
- vue-music ★621 - Vue 音乐搜索播放
- douban ★606 - 基于vue全家桶的精致豆瓣DEMO
- vue-Meizi ★604 - vue最新实战项目
- maizuo ★603 - vue/vuex/redux仿卖座网
- vue-WeChat ★558 - 基于Vue2高仿微信App的单页应用
- vue-demo-kugou ★500 - vuejs仿写酷狗音乐webapp
- vue2-manage ★457 - 基于 vue + element-ui 的后台管理系统
- zhihudaily-vue ★455 - 知乎日报web版
- vue-163-music ★448 - vue仿网易云音乐客户端版
- vue-axios-github ★448 - 登录拦截登出功能
- douban ★440 - 模仿豆瓣前端
- vue-shopping ★404 - 蘑菇街移动端
- vue2.0-taopiaopiao ★402 - vue2.0与express构建淘票票页面
- xyy-vue ★396 - 大学生交流平台
- easy-vue ★370 - 使用Vue实现简易web
- vue2.x-douban ★360 - Vue2实现简易豆瓣电影webApp
- vue2-MiniQQ ★351 - 基于Vue2实现的仿手机QQ单页面应用
- mi-by-vue ★291 - VueJS仿小米官网
- daily-zhihu ★275 - 基于Vue2的知乎日报单页应用
- vue-leancloud-blog ★268 - 一个前后端完全分离的单页应用
- VueMusic-PC ★260 - Vue.js高还原网易云音乐系列
- node-vue-server-webpack ★253 - Node.js+Vue.js+webpack快速开发框架
- beauty ★245 - 豆瓣美女clone
- vue-adminLte-vue-router ★243 - vue和adminLte整合应用
- vue-fis3 ★217 - 流行开源工具集成demo
- notepad ★216 - 本地存储的记事本
- vue-demo-maizuo ★210 - 使用Vue2全家桶仿制卖座电影
- Pixel-Web ★198 - 一个 Vue 微博客户端
- netease_yanxuan ★198 - vue版网易严选
- tmdb-app ★194 - TMDbVueJS应用
- vue-express-mongodb ★189 - 简单的前后端分离案例
- vue-zhihudaily ★187 - 知乎日报 Web 版本
- Vdo ★179 - VueJS与MD重构豆瓣
- vue-blog ★171 - 单用户博客
- Wuji ★168 - 吾记网页版
- hello-vue-django ★160 - 使用带有Django的vuejs的样板项目
- Zhihu-Daily-Vue.js ★157 - Vuejs单页网页应用
- tencent-sports ★154 - Vue全家桶仿腾讯体育
- gouyan-movie-vue ★151 - 基于vue的在线电影影讯网站
- x-blog ★145 - 开源的个人blog项目
- vue-musicApp ★132 - 使用vue全家桶制作的音乐播放器
- vue-cnode ★131 - vue单页应用demo
- webpack-vue-vueRouter ★130 - webpack及vue开发的简单项目实例
- vue-koa-demo ★128 - 使用Vue2和Koa1的全栈demo
- vueBlog ★127 - 前后端分离博客
- websocket_chat ★127 - 基于vue和websocket的多人在线聊天室
- houtai ★125 - 基于vue和Element的后台管理系统
- vue-toutiao ★121 - vuejs高仿今日头条移动端
- vue-cnode ★121 - 开源的CNode社区
- vue-mini-shop ★121 - VueJS在线商店
- photoShare ★120 - 基于图片分享的社交平台
- iview2-management-system ★119 - 后台管理系统解决方案简单示例
- doubanMovie ★119 - 豆瓣电影展示
- eleme-vue2 ★112 - 仿饿了么H5纯前端Vue版
- vue-zhihu-daily ★111 - 基于Vue全家桶开发的知乎日报
- Vue-News ★107 - 基于vue全家桶的仿知乎日报单页应用
- douban-movie ★107 - 仿豆瓣电影wap端
- generator-loopback-vue ★104 - 典型前后端分离项目模板
- vue-quasar-admin-example ★99 - 将Quasar和VueJS应用于SPA项目
- vue-zhihudaily-2.0 ★97 - 使用Vue2.0+vue-router+vuex创建的zhihudaily
- vue-todos ★95 - vue最新实战项目教程
- vue-music ★91 - 网易云音乐Demo
- vue-qqmusic ★90 - Vue全家桶+Mint-Ui打造高仿QQMusic
- vue2.x-Cnode ★88 - 基于vue全家桶的Cnode社区
- vue-ruby-china ★86 - VueJS框架搭建的rubychina平台
- doubanMovie-SSR ★85 - Vue豆瓣电影服务端渲染
- vue-jd ★76 - 京东移动web商城
- vue-nReader ★73 - 使用vue2.0 + vue-router + vuex 的一个多页面小说阅读webapp
- VueBlog ★73 - 前后端分离的个人博客
- Zhihu_Daily ★73 - 基于Vue和Nodejs的Web单页应用
- vue-koa2-login ★67 - 使用 VueJS & NodeJS 实现的登录注册
- webApp ★64 - Vue2的移动端webApp音乐播放器
- vue-trip ★64 - vue2做的出行webapp
- seeMusic ★63 - 跨平台云音乐播放器
- github-explorer ★63 - 寻找最有趣的GitHub库
- vue-cli-multipage-bootstrap ★60 - 将vue官方在线示例整合到组件中
- vue-XiaoMi-Shop ★59 - 高仿小米商城的项目
- Vue-NetEaseCloudMusic ★59 - 模仿IOS版网易云音乐的手机网站
- life-app-vue ★59 - 使用vue2完成多功能集合到小webapp
- doubanApp ★55 - 用vue2实现仿豆瓣app
- ios7-vue ★52 - 使用vue2.0 vue-router vuex模拟ios7
- canvas-vue ★50 - 一个Vue+Cnavas酷炫后台管理
- vue-bushishiren ★49 - 不是诗人应用
- vue-ssr-boilerplate ★48 - 精简版的ofvue-hackernews-2
- vuecommunity ★47 - vue.js中文社区
- vue-music163 ★47 - 音乐VueJS项目
- Vue2-MV ★45 - 仿网易云音乐MV的webapp
- musiccloudWebapp ★44 - 用vuejs仿网易云音乐
- cnode-vue ★40 - 基于vue和vue-router构建的cnodejs web网站SPA
- Framework7-VueJS ★38 - 使用移动框架的示例
- m-eleme ★37 - 基于Vue全家桶仿饿了么移动端webapp
- sls-vuex2-demo ★37 - vuex2商城购物车demo
- eagles ★36 - 各种组件封装
- Todos_Vuejs ★35 - vuejs2搭建的极简的todolist
- vue-cnode ★35 - 用 Vue 做的 CNode 官网
- HyaReader ★35 - 移动友好的阅读器
- Vue-Admin ★33 - 基于Vue2的Admin系统
- vue2-hybridapp-haoshiqi ★32 - 实现单页面webapp以及hybridapp
- zhihu-daily ★32 - 轻松查看知乎日报内容
- gank ★32 - gankio资源的阅读应用
- vue-h5plus ★31 - 前卫的vue及html5plus跨平台demo
- vue-cnode-mobile ★29 - 搭建cnode社区
- vue-weather ★26 - 基于vue.js 2.0的百度天气应用
- vue-user-center ★26 - vuejs直播类应用web端个人中心
- zhihu-daily-vue ★22 - 知乎日报
- vue-cnode ★22 - 使用cNode社区提供的接口
- vue-starter ★22 - VueJs项目的简单启动页
- node-vue-fabaocn ★21 - 基于 node 和 vue 实现的移动官网
- vue-memo ★20 - 用 vue写的记事本应用
- v-notes ★20 - 简单美观的记事本
- vue-flexible-app ★19 - vue开发的一个简易app
- simply-calculator-vuejs ★19 - 用VueJS实现简易计算器
- vue-dropload ★19 - 用以测试下拉加载与简单路由
- Vuejs-SalePlatform ★19 - vuejs搭建的售卖平台demo
- vue-shopping-mall ★16 - 基于Vue.js 2.x系列 + vue2-router + axios + iview 商城
- qqmusic ★13 - QQ音乐vue
- vue-weather ★12 - VueJS天气demo
配置ab为Nginx服务器压力测试
在运维工作中,压力测试是一项非常重要的工作。比如在一个网站上线之前,能承受多大访问量、在大访问量情况下性能怎样,这些数据指标好坏将会直接影响用户体验。
但是,在压力测试中存在一个共性,那就是压力测试的结果与实际负载结果不会完全相同,就算压力测试工作做的再好,也不能保证100%和线上性能指标相同。面对这些问题,我们只能尽量去想方设法去模拟。所以,压力测试非常有必要,有了这些数据,我们就能对自己做维护的平台做到心中有数。
目前较为常见的网站压力测试工具有webbench、ab(apache bench)、tcpcopy、loadrunner。
webbench由Lionbridge公司开发,主要测试每秒钟请求数和每秒钟数据传输量,同时支持静态、动态、SSL,部署简单,静动态均可测试。适用于小型网站压力测试(单例最多可模拟3万并发) 。
ab(apache bench)Apache自带的压力测试工具,主要功能用于测试网站每秒钟处理请求个数,多见用于静态压力测试,功能较弱,非专业压力测试工具。
tcpcopy基于底层应用请求复制,可转发各种在线请求到测试服务器,具有分布式压力测试功能,所测试数据与实际生产数据较为接近后起之秀,主要用于中大型压力测试,所有基于tcp的packets均可测试。
loadrunner压力测试界的泰斗,可以创建虚拟用户,可以模拟用户真实访问流程从而录制成脚本,其测试结果也最为逼真模拟最为逼真,并可进行独立的单元测试,但是部署配置较为复杂,需要专业人员才可以。
下面,笔者就以ab为例,来讲解一下网站在上线之前压力测试是如何做的。
ab是针对apache的性能测试工具,可以只安装ab工具。
ubuntu安装ab
apt-get install apache2-utils
centos安装ab
yum install httpd-tools
测试之前需要准备一个简单的html、一个php、一个图片文件。
分别对他们进行测试。
我们把这个三个文件放到nginx安装目录默认的html目录下,

准备之后我们就可以测试了
ab -kc 1000 -n 1000 http://localhost/ab.html
这个指令会使用1000个并发,进行连接1000次。结果如下
root@~# ab -kc 1000 -n 1000 http://www.nginx.cn/ab.html
This is ApacheBench, Version 2.3 <$Revision: 655654 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking www.nginx.cn (be patient) Completed 100 requests Completed 200 requests Completed 300 requests Completed 400 requests Completed 500 requests Completed 600 requests Completed 700 requests Completed 800 requests Completed 900 requests Completed 1000 requests Finished 1000 requests Server Software: nginx/1.2.3 Server Hostname: www.nginx.cn Server Port: 80 Document Path: /ab.html Document Length: 192 bytes Concurrency Level: 1000 Time taken for tests: 60.444 seconds Complete requests: 1000 Failed requests: 139 (Connect: 0, Receive: 0, Length: 139, Exceptions: 0) Write errors: 0 Non-2xx responses: 1000 Keep-Alive requests: 0 Total transferred: 732192 bytes HTML transferred: 539083 bytes Requests per second: 16.54 [#/sec] (mean) Time per request: 60443.585 [ms] (mean) Time per request: 60.444 [ms] (mean, across all concurrent requests) Transfer
rate: 11.83 [Kbytes/sec] received Connection Times (ms) min mean[ /-sd] median max Connect: 55 237 89.6 261 328 Processing: 58 5375 13092.8 341 60117 Waiting: 57 5337 12990.0 341 59870 Total: 386 5611 13083.7 572 60443 Percentage of the requests served within a certain time (ms) 50% 572 66% 606 75% 635 80% 672 90% 30097 95% 42004 98% 47250 99% 49250 100% 60443 (longest request)
对于php文件和图片文件可以使用同样指令进行,结果我就不贴出来了。
ab -kc 500 -n 5000 http://localhost/ab.php ab -kc 500 -n 5000 http://localhost/ab.gif
输出结果我们可以从字面意思就可以理解。
这里对两个比较重要的指标做下说明
比如
Requests per second: 16.54 [#/sec] (mean) Time per request: 60443.585 [ms] (mean) Requests per second: 16.54 [#/sec] (mean)
表示当前测试的服务器每秒可以处理16.54个静态html的请求事务,后面的mean表示平均。这个数值表示当前机器的整体性能,值越大越好。
Time per request: 60443.585 [ms] (mean)
单个并发的延迟时间,后面的mean表示平均。
隔离开当前并发,单独完成一个请求需要的平均时间。
顺带说一下两个Time per request区别
Time per request: 60443.585 [ms] (mean) Time per request: 60.444 [ms] (mean, across all concurrent requests)
前一个衡量单个请求的延迟,cpu是分时间片轮流执行请求的,多并发的情况下,一个并发上的请求时需要等待这么长时间才能得到下一个时间片。
计算方法Time per request: 60.444 [ms] (mean, across all concurrent requests)*并发数
通俗点说就是当以-c 10的并发下完成-n 1000个请求的同时,额外加入一个请求,完成这个求平均需要的时间。
后一个衡量性能的标准,它反映了完成一个请求需要的平均时间,在当前的并发情况下,增加一个请求需要的时间。
计算方法Time taken for tests: 60.444 seconds/Complete requests: 1000
通俗点说就是当以-c 10的并发下完成-n 1001个请求时,比完成-n1000个请求多花的时间。
你可以适当调节-c 和-n大小来测试服务器性能,借助htop指令来直观的查看机器的负载情况。
我的机器是盛大云的超微主机,平时负载cpu是1.7%,htop命令结果截图

加压后的负载100%,负载基本已经上来了。htop命令结果截图

看来我需要好好优化一下,或者就换台机器了。
ab的参数详细解释
普通的测试,使用-c -n参数配合就可以完成任务
格式: ./ab [options] [http://]hostname[:port]/path
参数:
-n 测试的总请求数。默认时,仅执行一个请求
-c 一次并发请求个数。默认是一次一个。
-H 添加请求头,例如 ‘Accept-Encoding: gzip\',以gzip方式请求。
-t 测试所进行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
-p 包含了需要POST的数据的文件.
-T POST数据所使用的Content-type头信息。
-v 设置显示信息的详细程度 – 4或更大值会显示头信息, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。 -V 显示版本号并退出。
-w 以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
-i 执行HEAD请求,而不是GET。
-C -C cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复。
LBS查询某经纬度范围内的数据性能优化
在实际的使用中,不太可能会发生需要计算该用户与所有其他用户的距离,然后再排序的情况,当用户数量达到一个级别时,
就可以在一个较小的范围里进行搜索,而非在所有用户中进行搜索.
所以对于这个例子,我增加了4个where条件,只对于经度和纬度大于或小于该用户1度(111公里)范围内的用户进行距离计算,同时对数据表中的经度和纬度两个列增加了索引来优化where语句执行时的速度.
最终的sql语句如下
$sql='select * from users_location where
latitude > '.$lat.'-1 and
latitude < '.$lat.'+1 and
longitude > '.$lon.'-1 and
longitude < '.$lon.'+1
order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.'* 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380 asc limit 10';
经过优化的sql大大提高了运行速度,在某些情况下甚至有100倍的提升.这种从业务角度出发,缩小sql查询范围的方法也可以适用在其他地方.
正确的计算距离公式是这样的:
public static double getDistance(double lat1, double lon1, double lat2, double lon2){
double radLat1 = lat1 * Math.PI / 180;
double radLat2 = lat2 * Math.PI / 180;
double a = radLat1 - radLat2;
double b = lon1 * Math.PI / 180 - lon2 * Math.PI / 180;
double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2)* Math.pow(Math.sin(b / 2), 2)));
s = s * 6378137.0;// 取WGS84标准参考椭球中的地球长半径(单位:m)
s = Math.round(s * 10000) / 10000;
return s;
}



