分类目录归档:未分类

Eclipse中添加注释模板

在写代码的时候会对相关文件进行说明和描述,因此在代码中添加注释模板是必要的。下面是我整理的注释模板,欢迎使用!

 

步骤

1、选中Eclipse的Windows——>Preferences——>Java——>Code Style——>Code Template——>Comments
选中Edit进行编辑

 

 

 

 

 

 

Files

/**  
 * @Title: ${file_name}
 * @Description: TODO(描述)
 * @author OriginalCoder
 * @date ${currentDate:date('yyyy-MM-dd hh:mm:ss')} 
 */  

 

Types

/**  
 * @ClassName: ${type_name}
 * @Description: TODO(描述)
 * ${tags}
 * @author OriginalCoder
 * @date ${currentDate:date('yyyy-MM-dd hh:mm:ss')} 
*/  

 

Fields

/**  
 * @Fields ${field} : TODO(描述)
 * @author OriginalCoder
 * @date ${currentDate:date('yyyy-MM-dd hh:mm:ss')} 
 */  

 

Constructors

/**  
 * @Title: ${enclosing_type}
 * @Description: ${enclosing_type}构造函数
 * ${tags}
 * @author OriginalCoder
 * @date ${currentDate:date('yyyy-MM-dd hh:mm:ss')} 
 */  

  

Methods

/**  
 * @Title: ${enclosing_method}
 * @Description: TODO(描述)
 * ${tags}
 * @author OriginalCoder
 * @date ${currentDate:date('yyyy-MM-dd hh:mm:ss')} 
 */  

  

Overriding methods

/**  
 * @Title: ${enclosing_method}
 * @Description: TODO(描述)
 * ${tags} 
 * ${see_to_overridden} 
 * @author OriginalCoder
 * @date ${currentDate:date('yyyy-MM-dd hh:mm:ss')} 
 */ 

  

 

Springboot集成mongodb

1、MongoDB介绍

NoSQL(NoSQL = Not Only SQL ),意即”不仅仅是SQL”。
在现代的计算系统上每天网络上都会产生庞大的数据量。
这些数据有很大一部分是由关系数据库管理系统(RDBMS)来处理。 1970年 E.F.Codd’s提出的关系模型的论文 “A relational model of data for large shared data banks”,这使得数据建模和应用程序编程更加简单。
通过应用实践证明,关系模型是非常适合于客户服务器编程,远远超出预期的利益,今天它是结构化数据存储在网络和商务应用的主导技术。
NoSQL 是一项全新的数据库革命性运动,早期就有人提出,发展至2009年趋势越发高涨。NoSQL的拥护者们提倡运用非关系型的数据存储,相对于铺天盖地的关系型数据库运用,这一概念无疑是一种全新的思维的注入。

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

 

 

 2、MongoDB的安装与启动

1. 下载mongodb安装包
地址 :https://pan.baidu.com/s/1BdRy4-ANoJfhwjyMGwH4-w
提取码:r5nh

https://www.mongodb.com/try/download/community

 

 

2. 下载mongodb的可视化工具
地址:https://pan.baidu.com/s/1fh3WP-JnkBhkED0QrCwlFg
提取码:m9f3

https://www.mongodb.com/try/download/compass

3、MongoDB的基本使用

1  MongoDB 创建数据库

命令:use DATABASE_NAME    (如果数据库不存在,则预创建数据库,如果对数据有操作则进行真实创建,否则切换到指定数据库。)

2 查看当前所在数据库
命令:db   (如果你想查看所有数据库,可以使用 show dbs 命令:)

3. 删除数据库
     先进入当前数据库,执行 db.dropDatabase()

4. 创建集合
      先进入当前数据库,执行 db.createCollection(“testmongo")

5. 删除集合
先进入当前数据库,执行 db.testmongo.drop()
1  MongoDB 插入
db.springboot.insert({"name":“springboot“,”page”:110,”number”:1})
db.springboot.insert({"name":“mybatis“,”page”:120,”number”:2})


2 查看数据
   db. springboot.find({"name":“springboot"} )

 

 

 

 

3  MongoDB 删除
db.springboot.remove({"name":“springboot“,”page”:110,”likes”:1000})


4 修改数据
   db.col.update({name ': springboot '},{$set:{page ':220'}},{multi:true})
(如果你要修改多条相同的文档,则需要设置 multi 参数为 true。 )

  

4、Springboot集成MongoDB

1.添加依赖
<dependency>         
<groupId>org.springframework.boot</groupId>        
<artifactId>spring-boot-starter-data-mongodb</artifactId>    </dependency>

2. 添加mongodb连接信息配置
spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test

5、MongoDB增删改查练习

参照:https://blog.csdn.net/u014453898/article/details/84146670

 

nginx 反向代理mysql及redis(TCP反向代理) 反向代理多个服务器

stream {        #定义stream;TCP模块是和HTTP一样的一个独立模块,所以不能设置在HTTP里面。
   upstream mysql-server {    #定义后端服务器
       server 192.168.38.37:3306 max_fails=3 fail_timeout=30s;     #定义具体server
   }

   upstream redis-server {
       server 192.168.38.47:6379 max_fails=3 fail_timeout=30s;
   }

   server {     #定义server
       listen 3306;                  #监听本机所有IP的3306端口
       proxy_connect_timeout 30s;    #连接超时时间
       proxy_timeout 30s;            #转发超时时间
       proxy_pass mysql-server;      #转发到具体服务器组
   }

   server {
       listen 192.168.38.27:6379;    #监听在本机的192.168.38.27的6379端口
       proxy_connect_timeout 30s;
       proxy_timeout 30s;
       proxy_pass redis-server;
   }
}
TCP反向代理是基于IP和端口号;这个设置不要设置在http模块中,tcp和http是两个独立的模块,不要设置在一起。

  

示例配置:

stream{
    #proxy 192.168.1.222
	upstream proxy222{
        server 192.168.1.222:502 weight=1 max_fails=2 fail_timeout=60s;
    }
	server{
			listen 512;
			proxy_connect_timeout 30s;
			proxy_timeout 30s;
			proxy_pass proxy222;
	}
	#proxy 192.168.1.224
    upstream proxy224{
        server 192.168.1.224:502 weight=1 max_fails=2 fail_timeout=60s;
    }
	server{
			listen 513;
			proxy_connect_timeout 30s;
			proxy_timeout 30s;
			proxy_pass proxy224;
	}
	#proxy 192.168.1.225
    upstream proxy225{
        server 192.168.1.225:502 weight=1 max_fails=2 fail_timeout=60s;
    }
	server{
			listen 514;
			proxy_connect_timeout 30s;
			proxy_timeout 30s;
			proxy_pass proxy225;
	}
}

  

各种数据类型转换为二进制ByteArrayConveter

package com.ioufev;

import java.nio.ByteOrder;

public class ByteArrayConveter {
 
	// char转换为byte[2]数组
	public static byte[] getByteArray(char c) {
		byte[] b = new byte[2];
		b[0] = (byte) ((c & 0xff00) >> 8);
		b[1] = (byte) (c & 0x00ff);
		return b;
	}
 
	// 从byte数组的index处的连续两个字节获得一个char
	public static char getChar(byte[] arr, int index) {
		return (char) (0xff00 & arr[index] << 8 | (0xff & arr[index + 1]));
	}
	// short转换为byte[2]数组
	public static byte[] getByteArray(short s) {
		byte[] b = new byte[2];
		b[0] = (byte) ((s & 0xff00) >> 8);
		b[1] = (byte) (s & 0x00ff);
		return b;
	}
	// 从byte数组的index处的连续两个字节获得一个short
	public static short getShort(byte[] arr, int index) {
		return (short) (0xff00 & arr[index] << 8 | (0xff & arr[index + 1]));
	}
	// int转换为byte[4]数组
	public static byte[] getByteArray(int i) {
		byte[] b = new byte[4];
		b[0] = (byte) ((i & 0xff000000) >> 24);
		b[1] = (byte) ((i & 0x00ff0000) >> 16);
		b[2] = (byte) ((i & 0x0000ff00) >> 8);
		b[3] = (byte)  (i & 0x000000ff);
		return b;
	}
	// 从byte数组的index处的连续4个字节获得一个int
	public static int getInt(byte[] arr, int index) {
		return 	(0xff000000 	& (arr[index+0] << 24))  | 
				(0x00ff0000 	& (arr[index+1] << 16))  | 
				(0x0000ff00 	& (arr[index+2] << 8))   | 
				(0x000000ff 	&  arr[index+3]);
	}
	// float转换为byte[4]数组
	public static byte[] getByteArray(float f) {
		int intbits = Float.floatToIntBits(f);//将float里面的二进制串解释为int整数
		return getByteArray(intbits);
	}
	// 从byte数组的index处的连续4个字节获得一个float
	public static float getFloat(byte[] arr, int index) {
		return Float.intBitsToFloat(getInt(arr, index));
	}
	// long转换为byte[8]数组
	public static byte[] getByteArray(long l) {
		byte b[] = new byte[8];
		b[0] = (byte)  (0xff & (l >> 56));
		b[1] = (byte)  (0xff & (l >> 48));
		b[2] = (byte)  (0xff & (l >> 40));
		b[3] = (byte)  (0xff & (l >> 32));
		b[4] = (byte)  (0xff & (l >> 24));
		b[5] = (byte)  (0xff & (l >> 16));
		b[6] = (byte)  (0xff & (l >> 8));
		b[7] = (byte)  (0xff & l);
		return b;
	}
	// 从byte数组的index处的连续8个字节获得一个long
	public static long getLong(byte[] arr, int index) {
		return 	(0xff00000000000000L 	& ((long)arr[index+0] << 56))  | 
				(0x00ff000000000000L 	& ((long)arr[index+1] << 48))  | 
				(0x0000ff0000000000L 	& ((long)arr[index+2] << 40))  | 
				(0x000000ff00000000L 	& ((long)arr[index+3] << 32))  |
				(0x00000000ff000000L 	& ((long)arr[index+4] << 24))  | 
				(0x0000000000ff0000L 	& ((long)arr[index+5] << 16))  | 
				(0x000000000000ff00L 	& ((long)arr[index+6] << 8))   | 
				(0x00000000000000ffL 	&  (long)arr[index+7]);
	}
	// double转换为byte[8]数组
	public static byte[] getByteArray(double d) {
		long longbits = Double.doubleToLongBits(d);
		return getByteArray(longbits);
	}
	// 从byte数组的index处的连续8个字节获得一个double
	public static double getDouble(byte[] arr, int index) {
		return Double.longBitsToDouble(getLong(arr, index));
	}
 
	public static void main(String[] args) {
		System.out.println(ByteOrder.nativeOrder());
		if(args.length < 1){
			System.out.println("enter 'char' test method about char");
			System.out.println("enter 'short' test method about short");
			System.out.println("enter 'int' test method about int");
			System.out.println("enter 'float' test method about float");
			System.out.println("enter 'long' test method about long");
			System.out.println("enter 'double' test method about double");
			return;
		}
		if(args[0].equals("char")){
			char c = 'u0000';
			while( c < 'uffff'){
				System.out.println(getChar(getByteArray(c),0));
				c++;
			}
		}else if(args[0].equals("short")){
			short s = Short.MIN_VALUE;
			while( s < Short.MAX_VALUE){
				System.out.println(getShort(getByteArray(s), 0));
				s++;
			}
		}else if(args[0].equals("int")){
			int i = Integer.MIN_VALUE;
			while( i < Integer.MAX_VALUE){
				System.out.println(getInt(getByteArray(i), 0));
				i++;
			}
		}else if(args[0].equals("float")){
			float f = Float.MIN_VALUE;
			while(f < Float.MAX_VALUE){
				System.out.println(getFloat(getByteArray(f), 0));
				f+=1.1111f;
			}
		}else if(args[0].equals("long")){
			long l = Long.MIN_VALUE;
			while(l < Long.MAX_VALUE){
				System.out.println(getLong(getByteArray(l), 0));
				l++;
			}
		}else if(args[0].equals("double")){
			double d = Double.MIN_VALUE;
			while(d < Double.MAX_VALUE){
				System.out.println(getDouble(getByteArray(d), 0));
				d+=1.111D;
			}
		}
	}
}

  

JAVA实现FLOAT32 类型转换大小端转换,从(1234)到 (3412) 交换字节模式

示例3,当写入287454020时,对应的十六进制为0x11223344, 经过使用不同数据类型转换字节序后,发送和接收顺序如下所示:

    • FLOAT32 (3412) 小端交换字节模式 33,44,11,22
    • FLOAT32 (1234) 大端模式 11,22,33,44
    • FLOAT32(2143) 大端交换字节模式 22,11,44,33
    • FLOAT32(4321) 小端模式 44,33,22,11

1.实现【FLOAT32 (3412) 小端交换字节模式 33,44,11,22】这种模式

实现思路

 

1 2 3 4  init


b[0] = (byte) (fbit >> 16)
b[1] = (byte) (fbit) 

b[0]= 0 0 1 2
b[1]= 1 2 3 4


l = b[0]
0 0 1 2

l &= 0xffff
0 0 1 2



l |= ((long) b[2] << 16)
3 4 0 0
0 0 1 2
-------|
3 4 1 3

  

 Java实现代码:

//方法1:  
//(3412) 小端交换字节模式 private float big2Little(float big){ // 把float转换为byte[] int fbit = Float.floatToIntBits(big); byte[] b = new byte[4]; b[0] = (byte) (fbit >> 16); b[1] = (byte) (fbit); int l; l = b[0]; l &= 0xff; l |= ((long) b[2] << 16); float little = Float.intBitsToFloat(l); return little; }

//方法2:    
private float big2Little(float big){
        
    	// 把float转换为byte[]
    	int fbit = Float.floatToIntBits(big);

    	int a = fbit << 16;
    	a &= 0xFFFF0000;
    	System.out.println("a:"+ a);

        int b = fbit >> 16;
    	b &= 0xFFFF;
        System.out.println("b:"+ b);
        
        int l;
        l = a|b;
        
        System.out.println("l:"+l);
        
        float little = Float.intBitsToFloat(l);
        return little;
    }

  

注意:l &= 0xff;  实现的功能为高位清0  因为【汇编语言中的逻辑右移(SHR)是将各位依次右移指定位数,然后在左侧补0,算术右移(SAR)是将各位依次右移指定位数,然后在左侧用原符号位补齐】

参照  :移位操作和二进制知识

 2.实现【FLOAT32(4321) 小端模式 44,33,22,11】这种模式

 实现思路:

1 2 3 4  init


b[0]= 0 0 0 1
b[1]= 0 0 1 2
b[2]= 0 1 2 3
b[3]= 1 2 3 4

l = b[0]
0 0 0 1
l &= 0xff
0 0 0 1

l |= ((long) b[1] << 8)
0 1 2 0
0 0 0 1
-------|
0 1 2 1

l &= 0xffff
0 0 2 1

l |= ((long) b[2] << 16)
#1 2 3 0 0
2 3 0 0
0 0 2 1
-------|
2 3 2 1

l &= 0xffffff  
0 3 2 1

l |= ((long) b[3] << 24)
4 0 0 0
0 3 2 1
-------|
4 3 2 1

 

  Java实现代码:

 

//大端(1234)转小端(4321)
private float big2Little(float big){
    // 把float转换为byte[]
    int fbit = Float.floatToIntBits(big);

    byte[] b = new byte[4];
    b[0] = (byte) (fbit >> 24);
    b[1] = (byte) (fbit >> 16);
    b[2] = (byte) (fbit >> 8);
    b[3] = (byte) (fbit);
    
    int l;
    l = b[0];
    l &= 0xff;
    l |= ((long) b[1] << 8);
    l &= 0xffff;
    l |= ((long) b[2] << 16);
    l &= 0xffffff;
    l |= ((long) b[3] << 24);
    float little = Float.intBitsToFloat(l);
    return little;
}

 

二进制走读执行:

FLOAT32 (3412)

80 00 44 2c       (1234)端  

2c 44 00 80       (4321)端

大端转小端过程

1000 0000 0000 0000 0100 0100 0010 1100  init

b[0]=init>>24
0000 0000 0000 0000 0000 0000 1000 0000

b[1]=init>>16
0000 0000 0000 0000 1000 0000 0000 0000

b[2]=init>>8
0000 0000 1000 0000 0000 0000 0100 0100

b[3]=init
1000 0000 0000 0000 0100 0100 0010 1100

l = b[0]
0000 0000 0000 0000 0000 0000 1000 0000

l &= 0xff
0000 0000 0000 0000 0000 0000 1000 0000
0000 0000 0000 0000 0000 0000 1111 1111
----------------------------------------&
0000 0000 0000 0000 0000 0000 1000 0000

l |= ((long) b[1] << 8)

0000 0000 1000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 1000 0000
----------------------------------------|
0000 0000 1000 0000 0000 0000 1000 0000

l &= 0xffff

0000 0000 1000 0000 0000 0000 1000 0000
0000 0000 0000 0000 1111 1111 1111 1111
----------------------------------------&
0000 0000 0000 0000 0000 0000 1000 0000

l |= ((long) b[2] << 16)

0000 0000 0100 0100 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 1000 0000
----------------------------------------|
0000 0000 0100 0100 0000 0000 1000 0000

l &= 0xffffff

0000 0000 0100 0100 0000 0000 1000 0000
0000 0000 1111 1111 1111 1111 1111 1111
---------------------------------------&
0000 0000 0100 0100 0000 0000 1000 0000

l |= ((long) b[3] << 24)
0010 1100 0000 0000 0000 0000 0000 0000
0000 0000 0100 0100 0000 0000 1000 0000
-----------------------------------------|
0010 1100 0100 0100 0000 0000 1000 0000
2    c    4     4   0    0   8    0


1000 0000 0000 0000 0100 0100 0010 1100

  

基于阿里巴巴-Mysql规约/规范 总结

  • 一:建表规约

 

1. 【强制】表达是与否概念的字段,必须使用is_xxx的方式命名,数据类型是unsignedtinyint

 ( 1表示是,0表示否),此规则同样适用于odps建表。

 说明:任何字段如果为非负数,必须是unsigned。

2. 【强制】表名、字段名必须使用小写字母或数字;禁止出现数字开头,禁止两个下划线中间只

  出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。

  正例:getter_admin,task_config,level3_name

  反例:GetterAdmin,taskConfig,level_3_name

3. 【强制】表名不使用复数名词。

  说明:表名应该仅仅表示表里面的实体内容,不应该表示实体数量,对应于DO类名也是单数

  形式,符合表达习惯。

4. 【强制】禁用保留字,如desc、range、match、delayed等,参考官方保留字。

5. 【强制】唯一索引名为uk_字段名;普通索引名则为idx_字段名。

  说明:uk_即 unique key;idx_即index的简称。

6. 【强制】小数类型为decimal,禁止使用float和double。

  说明:float和double在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不

  正确的结果。如果存储的数据范围超过decimal的范围,建议将数据拆成整数和小数分开存储。

7. 【强制】如果存储的字符串长度几乎相等,使用CHAR定长字符串类型。

8. 【强制】varchar是可变长字符串,不预先分配存储空间,长度不要超过5000,如果存储长度

  大于此值,定义字段类型为TEXT,独立出来一张表,用主键来对应,避免影响其它字段索引

  效率。

9. 【强制】表必备三字段:id, gmt_create, gmt_modified。

  说明:其中id必为主键,类型为unsigned bigint、单表时自增、步长为1;分表时改为从

      TDDL Sequence取值,确保分表之间的全局唯一。gmt_create,gmt_modified的类型均为

      date_time类型。

10.【推荐】表的命名最好是加上“业务名称_表的作用”,避免上云梯后,再与其它业务表关联

  时有混淆。

  正例:tiger_task / tiger_reader / mpp_config

11.【推荐】库名与应用名称尽量一致。

12.【推荐】如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。

13.【推荐】字段允许适当冗余,以提高性能,但是必须考虑数据同步的情况。冗余字段应遵循:

1)不是频繁修改的字段。

2)不是varchar超长字段,更不能是text字段。

  正例:各业务线经常冗余存储商品名称,避免查询时需要调用IC服务获取。

14.【推荐】单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。

  说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

  反例:某业务三年总数据量才2万行,却分成1024张表,问:你为什么这么设计?答:分1024

  张表,不是标配吗?

15.【参考】合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索

  速度。

  正例:人的年龄用unsignedtinyint(表示范围0-255,人的寿命不会超过255岁);海龟就

  必须是smallint,但如果是太阳的年龄,就必须是int;如果是所有恒星的年龄都加起来,那

  么就必须使用bigint。
  •   索引规约
1. 【强制】业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。

  说明:不要以为唯一索引影响了insert速度,这个速度损耗可以忽略,但提高查找速度是明

  显的;另外,即使在应用层做了非常完善的校验和控制,只要没有唯一索引,根据墨菲定律,

  必然有脏数据产生。

2. 【强制】超过三个表禁止join。需要join的字段,数据类型保持绝对一致;多表关联查询时,

  保证被关联的字段需要有索引。

  说明:即使双表join也要注意表索引、SQL性能。

3. 【强制】在varchar字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据

  实际文本区分度决定索引长度。

  说明:索引的长度与区分度是一对矛盾体,一般对字符串类型数据,长度为20的索引,区分

  度会高达90%以上,可以使用count(distinct left(列名,索引长度))/count(*)的区分度来

  确定。

4. 【强制】页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。

  说明:索引文件具有B-Tree的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索

  引。

5. 【推荐】如果有order by的场景,请注意利用索引的有序性。order by 最后的字段是组合索

  引的一部分,并且放在索引组合顺序的最后,避免出现file_sort的情况,影响查询性能。

  正例:where a=? and b=? order by c; 索引:a_b_c

  反例:索引中有范围查找,那么索引有序性无法利用,如:WHERE a>10 ORDER BY b; 索引a_b

  无法排序。

6. 【推荐】利用覆盖索引来进行查询操作,来避免回表操作。

  说明:如果一本书需要知道第11章是什么标题,会翻开第11章对应的那一页吗?目录浏览一

  下就好,这个目录就是起到覆盖索引的作用。

  正例:IDB能够建立索引的种类:主键索引、唯一索引、普通索引,而覆盖索引是一种查询的

  一种效果,用explain的结果,extra列会出现:using index.

7. 【推荐】利用延迟关联或者子查询优化超多分页场景。

  说明:MySQL并不是跳过offset行,而是取offset+N行,然后返回放弃前offset行,返回N

  行,那当offset特别大的时候,效率就非常的低下,要么控制返回的总页数,要么对超过特

  定阈值的页数进行SQL改写。

  正例:先快速定位需要获取的id段,然后再关联:

      SELECT a.* FROM 表1a, (selectid from 表1 where 条件 LIMIT 100000,20 ) b where a.id=b.id

8. 【推荐】SQL性能优化的目标:至少要达到 range级别,要求是ref级别,如果可以是consts

  最好。

  说明:

  1)consts单表中最多只有一个匹配行(主键或者唯一索引),在优化阶段即可读取到数据。

  2)ref指的是使用普通的索引。(normal index)

  3)range对索引进范围检索。

  反例:explain表的结果,type=index,索引物理文件全扫描,速度非常慢,这个index级别

  比较range还低,与全表扫描是小巫见大巫。

9. 【推荐】建组合索引的时候,区分度最高的在最左边。

  正例:如果wherea=?andb=? ,a列的几乎接近于唯一值,那么只需要单建idx_a索引即可。

  说明:存在非等号和等号混合判断条件时,在建索引时,请把等号条件的列前置。如:wherea>?

      and b=? 那么即使a的区分度更高,也必须把b放在索引的最前列。

10.【参考】创建索引时避免有如下极端误解:

  1)误认为一个查询就需要建一个索引。

  2)误认为索引会消耗空间、严重拖慢更新和新增速度。

  3)误认为唯一索引一律需要在应用层通过“先查后插”方式解决。
  •   SQL规约
1. 【强制】不要使用count(列名)或count(常量)来替代count(*),count(*)就是SQL92定义的

  标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

  说明:count(*)会统计值为NULL的行,而count(列名)不会统计此列为NULL值的行。

2. 【强制】count(distinct col) 计算该列除NULL之外的不重复数量。注意 count(distinct

      col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为0。

3. 【强制】当某一列的值全是NULL时,count(col)的返回结果为0,但sum(col)的返回结果为

     NULL,因此使用sum()时需注意NPE问题。

  正例:可以使用如下方式来避免sum的NPE问题:SELECTIF(ISNULL(SUM(g)),0,SUM(g))FROM

     table;

4. 【强制】使用ISNULL()来判断是否为NULL值。注意:NULL与任何值的直接比较都为NULL。

  说明:

  1) NULL<>NULL的返回结果是NULL,不是false。

  2) NULL=NULL的返回结果是NULL,不是true。

  3) NULL<>1的返回结果是NULL,而不是true。

5. 【强制】在代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。

6. 【强制】不得使用外键与级联,一切外键概念必须在应用层解决。

  说明:(概念解释)学生表中的student_id是主键,那么成绩表中的student_id则为外键。

  如果更新学生表中的student_id,同时触发成绩表中的student_id更新,则为级联更新。外

  键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据

  库更新风暴的风险;外键影响数据库的插入速度。

7. 【强制】禁止使用存储过程,存储过程难以调试和扩展,更没有移植性。

8. 【强制】IDB数据订正时,删除和修改记录时,要先select,避免出现误删除,确认无误才能

  提交执行。

9. 【推荐】in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控

  制在1000个之内。

10.【参考】因阿里巴巴全球化需要,所有的字符存储与表示,均以utf-8编码,那么字符计数方

  法注意:

  说明:

      SELECT LENGTH("阿里巴巴"); 返回为12

      SELECT CHARACTER_LENGTH("阿里巴巴"); 返回为4

  如果要使用表情,那么使用utfmb4来进行存储,注意它与utf-8编码。

11.【参考】TRUNCATE TABLE 比 DELETE速度快,且使用的系统和事务日志资源少,但TRUNCATE

  无事务且不触发trigger,有可能造成事故,故不建议在开发代码中使用此语句。

  说明:TRUNCATE TABLE 在功能上与不带 WHERE子句的 DELETE语句相同。
  •   ORM规约
1. 【强制】在表查询中,一律不要使用 *作为查询的字段列表,需要哪些字段必须明确写明。

  说明:1)增加查询分析器解析成本。2)增减字段容易与resultMap配置不一致。

2. 【强制】POJO类的boolean属性不能加is,而数据库字段必须加is_,要求在resultMap中

  进行字段与属性之间的映射。

  说明:参见定义POJO类以及数据库字段定义规定,在sql.xml增加映射,是必须的。

3. 【强制】不要用resultClass当返回参数,即使所有类属性名与数据库字段一一对应,也需要

  定义;反过来,每一个表也必然有一个与之对应。

  说明:配置映射关系,使字段与DO类解耦,方便维护。

4. 【强制】xml配置中参数注意使用:#{},#param#不要使用${}此种方式容易出现SQL注入。

5. 【强制】iBATIS自带的queryForList(String statementName,int start,int size)不推荐使

  用。

  说明:其实现方式是在数据库取到statementName对应的SQL语句的所有记录,再通过subList

  取start,size的子集合,线上因为这个原因曾经出现过OOM。

  正例:在sqlmap.xml中引入 #start#, #size#

      Map<String, Object> map = new HashMap<String,Object>();

      map.put("start", start);

      map.put("size", size);

6. 【强制】不允许直接拿HashMap与HashTable作为查询结果集的输出。

  反例:某同学为避免写一个<resultMap>,直接使用HashTable来接收数据库返回结果,结果

  出现日常是把bigint转成Long值,而线上由于数据库版本不一样,解析成BigInteger,导

  致线上问题。

7. 【强制】更新数据表记录时,必须同时更新记录对应的gmt_modified字段值为当前时间。

8. 【推荐】不要写一个大而全的数据更新接口,传入为POJO类,不管是不是自己的目标更新字

  段,都进行update table set c1=value1,c2=value2,c3=value3; 这是不对的。执行SQL时,

  尽量不要更新无改动的字段,一是易出错;二是效率低;三是binlog增加存储。

9. 【参考】@Transactional事务不要滥用。事务会影响数据库的QPS,另外使用事务的地方需要

  考虑各方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿、统计修正等。

10.【参考】<isEqual>中的compareValue是与属性值对比的常量,一般是数字,表示相等时带上

  此条件;<isNotEmpty>表示不为空且不为null时执行;<isNotNull>表示不为null值时执行。

  

数据中心运维管理方案

第一章 某数据中心基础运维概述

某数据中心的基础运维工作主要包含包括四个部分:基础环境、网络、服务器存储和基础软件。

其中第一部分机房基础环境部分,包含机柜位置、空调、消防、安防、弱电、UPS等最基础的机房环境设施。需要对这些基础环境部分进行运维维护,确保整个机房环境正常稳定。

第二部分为网络环境,包括当前数据中心所有的交换机、路由器等设备,以及由这些设备组成的所有网络,需要监控网络运行情况并提出网络风险评估,定期对网络进行优化配置,提高网络运行效率,保证整个网络环境的安全。

第三部分服务器和存储部分,包含整个数据中心的小型机、服务器、存储设备、SAN交换机等设备。这些设备支撑着整个业务系统,是非常重要的基础硬件环境。需要监控这些设备的运行情况,及时处理出现的问题和变更,并基于整个环境提供优化。

第四部分为基础软件部分,包括各种操作系统、数据库、中间件、备份软件等等。要求这些软件可以正常工作,并优化配置,为平台和工作站正常服务,当这些软件出现问题时,能发现并提出解决方案;可以协助应用人员解决故障或进行对应的变更、升级等操作。

本方案将基于这几个方面进行设计,确保数据中心正常、高效运行。

 

第二章 数据中心运维分类

某数据中心运维团队将根据当前数据中心的实际情况和对应的管理制度,通过主动性、预防性维护,执行日常维护作业计划,对告警、性能、运行状态进行检查分析,及时进行数据备份,并定期对备份数据进行恢复性测试验证,对系统运行质量进行分析,并进行维护记录。对监控或维护中发现的问题及时处理,消除隐患,保障平台的稳定运行。我们将基于以下几个方面对运维工作进行描述

2.1 基础环境运维管理

针对基本的机房环境设施,我们的工作内容包含以下这些内容:

1) 机房机柜摆放规划和机柜管理;

2) 服务器和网络设备摆放规划和日常管理;

3) 设备出入机房审批登记管理;

4) 内部人员出入机房审批登记管理;

5) 外部来宾机房参观审批登记管理;

6) 机房电力系统监控、问题及时上报;

7) 消防监控系统监控、接收报警短信和联系第三方;

8) 空调报警系统监控、接收报警短信和联系第三方;确认空调运行状态良好。清洁机房的空调防尘网。

9) 温湿度报警监控、接受报警短信和联系专业第三方;

10) 漏水报警系统监控、接受报警短信和联系专业第三方;

11) IC卡门禁系统日常运维;

12) 视频监控系统日常运维;

13) UPS报警系统监控和联系第三方;

14) 机房资产管理系统(CMDB)。

15) 机房环境。清理机房的杂物,将机房物品定置。清洁机房门窗、地面。定期清洁电池室的地面;检查机房所有与外界的空洞是否已严密封堵,严密防鼠;检查机房玻璃、地板、天花板、通气口,墙体表面是否正常,外观是否完好,有否出现老化现象。检查机房是否有漏水现象。检查机房墙壁是否有渗水现象。填写巡检记录,有问题及时报告。

16) 巡视电池间;检查电池工作状态。

17) 确认机房照明良好,出现问题及时报告。

18) 视频网络播放系统。定期检查可用性,有问题及时与专业第三方公司联系解决。

19) 填写巡检记录。

2.2 网络运维管理

针对数据中心的网络部分,运维内容主要包含以下内容:

1) 测试网络接入速度,监控网络访问可用性和访问质量,出现问题第一时间直接联系接入商解决。

2) 网络接入商变化时,配合网络接入商对网络变更方案的可行性审查、问题审查。配合网络接入商更替施工。

3) 局域网。本地局域网日常管理和维护;VLAN 划分;网络性能优化;故障排除;网络节点周期性检查,发现潜在问题,并解决。

4) 无线局域网。负责无线局域网的日常管理和维护;客户端不能正常接入网络的故障排除;网络性能优化;故障排除;网络节点周期性检查,发现潜在问题并解决。

5) 远程接入。制定VPN使用策略,实施VPN用户日常远程接入服务器的管理,以及性能优化和故障排除等。

6) 网络病毒查杀和网络安全保护。

7) 根据实际项目或安排而产生的其他工作。

2.3 服务器和存储运维管理

2.3.1 服务器运行情况及性能监测

数据中心运维团队将通过综合监控系统实施7*24小时平台设备监控,发现告警,并进行处理,解决问题。对系统运行进行实时检查。对监控或维护中发现的问题及时处理,消除隐患,保障平台的稳定运行。并且还提供针对各服务器物理资源的使用情况和操作系统的运行情况、进行实时监控,提供服务器安全监测报告。

主机性能监控的检查列表包括:

 CPU利用率

 内存使用情况

 交换区使用情况

 磁盘I/O情况

 关键文件系统的状态

 重要进程的运行情况(例程数量、消耗CPU、占用内存)

 操作系统的各类日志文件

网络、端口信息

 ……

运维团队需根据检查列表进行日常检查,并不断地改进日常检查列表,以满足对系统监控的需要。

2.3.2 服务器软硬件兼容性检查

数据中心运维团队在维护系统稳定运行的同时,需主动收集系统关键补丁、软件补丁、硬件微码等信息,在通过数据中心专家评审的前提下,对相关设备进行升级服务,并在升级完成后配合应用方对系统进行测试。升级前后需要和应用方及时做好沟通确认工作,确保不会产生兼容性导致的故障。

2.3.3 磁盘阵列设备管理

运维团队需要对磁盘阵列设备及其相关的部件(如硬盘、控制器等)进行编号,并记录在案,对软件设置中的参数也要进行详细的记录,并在每次变更后及时更新相关的信息。

除此之外,运维团队定期(暂定每半年)对于每个服务器的系统容量监测的审核,并制定相应的容量规划,主要监测文件系统的空间、数据库的空间资源利用情况,分析资源利用趋势,并提供资源情况报表。

文件系统空间管理

 定期检查文件系统的空间使用情况,根据业务发展需求和新业务的增加,制定合理的空间分配方案,新增、修改或删除空间。

对文件系统空间的使用进行监控,发现空间使用不合理或需要清理的协调解决。

数据库空间管理

应实时监测数据存储空间的使用情况,根据业务数据的数据量、数据结构以及增长速度,制定合适的数据存储和结构优化策略,动态增加新的空间以存放业务数据;
定期检查数据存储空间的使用情况,根据实际情况规划增加新的空间,填写数据库空间新增/修改/删除申请表,经审核后实施,并更新数据库配置状况记录表。

2.3.4 机柜、电源、网线布局管理

运维团队对于新上架安装的设备,需要进行拍照留档,确认各线路位置,并对服务器的电源部分进行编号整理,最终登记在册。

2.3.5 协助第三方维护

对于由专业第三方提供运维的设备,设备出现问题后运维团队需及时通知第三方并告知采购人,视情况严重性,决定是否启动应急预案;配合第三方服务商一起排查和解决问题,实施为了解决故障而进行的系统软硬件的补丁、升级及维护工作。独立处理初级系统故障,与第三方厂商或服务商配合解决高级别系统故障。记录问题、故障的解决办法及解决过程。做出临时的配置变更以排除故障,在必要的时候,提出永久性配置变更建议。

2.4 基础软件运维管理

2.4.1 操作系统

运维团队充分保障服务器操作系统的稳定运行,将提供以下服务内容:

1) 系统升级

运维团队在维护系统稳定运行的同时,需主动收集系统关键补丁、软件补丁等信息,在通过数据中心专家评审的前提下,对相关系统进行升级服务,并在升级完成后配合应用方对系统进行测试。升级前后需要和应用方及时做好沟通确认工作,确保不会产生兼容性导致的故障。

2) 操作系统稳定性监控定时查看操作系统日志及IIS日志,查看CPU、内存占用率,排除故障。

3) 权限与文件管理

服务器应明确责任人及管理帐号持有人,不应出现多人单帐户,单人多帐户的情况,不利于在服务器出现问题后,对服务器进行操作维护、查找问题。

4) 定期检查磁盘空间

进行磁盘文件排列的优化和错误扫描,并处理错误;安全地删除系统各路径下存放的临时文件、无用文件、备份文件等等,完全释放磁盘空间。

5) 维护系统注册表。

6) 系统配置。优化系统配置,关闭无用服务和端口,以最适合系统运行方式,最小化安装等。维护系统配置文档。

7) 负责系统用户管理,如增加、删除用户、重置用户密码、管理用户权限等。进行系统用户管理时,记录所有相关的系统变更。

8) 对于新安装的服务器,运维团队应负责安装必要的应用软件:如远程监控工具、备份工具、防病毒软件等。

2.4.2 数据库

运维团队将对数据进行日常维护,在数据库性能监控的检查列表包括:

资源使用情况

 运行情况

 数据库进程状态

 数据库连接状态

 数据库进程使用资源

 数据库的表空间(数据表空间、索引空间、临时表空间等等)使用情况;

 数据库日志空间

回滚段使用情况

 数据库锁的数量

 死锁的发生、死锁资源

 数据库碎片的数量

 磁盘I/O

 数据库运行日志

 数据库用户登录情况

 监控结果应做登记管理,如实记录系统日常运行状况及异常情况,填写日常运行情况记录表;

 ……

除此之外,数据库的运维工作还包含一些其他工作,如:

1) 数据库备份和恢复

2) 做好备份计划,工程师定时完成,因备份占用内存较大,在访问量大的情况下进行。当出现数据问题时,向采购人管理部门通报,说明数据情况,后恢复。

3) 访问性能优化及数据库同步

4) 服务器管理人员需记录详细的设置;数据库如需要同步,应明确同步时间或实时同步等方式。

5) 数据库日志和表空间,定期进行整理,问题解决。

2.4.3 中间件

运维团队针对中间件的运维工作,内容如下:

1) Oracle Weblogic,辅助开发公司进行配置,保留配置文档。模块配置与更新,配合第三方配置.java及wls的版本及更新工作。操作系统模块配置与更新,配合第三方配置操作系统到可用的版本及更新。配合反馈第三方解决服务错误日志中的问题。

2) 新软件安装,收集安装光盘、安装合同(可复印学习)、使用说明书、授权书(Liscense)。纸质版文件扫描后入库,电子版文件进入配置库。

2.4.4 备份系统

为保证在系统崩溃或停止运行时能尽快恢复系统,将制定相关的数据备份制度。应针对不同系统制定备份方案,应包括备份方法、频率等。数据备份包括定期和不定期备份。重要数据应每月进行全备份和增量备份;不定期备份应该在数据变更后立即进行,更新前的备份按需要保存一定时间。

2.4.5 应用系统

当前的应用系统及相关的开发工作由第三方公司负责,运维团队主要起配合作用,相关的工作内容如下:

1) 当应用出现问题,及时联系第三方解决,并做问题记录。

2) 配合第三方进行操作系统、数据库和中间件的系统配置,并做配置记录,在有授权运维的系统中,熟悉应用系统维护方法。

3) 配合第三方新应用系统上线,需收集安装文件,源代码,部署文档、运维文档。扫描后,入配置库。与合同库相关联,记录维护期间联系人,原公司质保期。

4) 每日上班后、下班前检查可用性,确认无灾难性问题、黑客篡改问题。

5) 其他待完成工作,根据实际情况来处理。

 

第三章 运维工作内容

3.1 日常维护工作

运维团队的值班安排分三班,保持7×24小时的人员安排,在任何时间数据中心都由值班人员。运维团队根据数据中心的运维管理制度,通过主动性、预防性维护,执行日常维护作业计划,对告警、性能、运行状态进行检查分析,及时进行数据备份,并定期对备份数据进行恢复性测试验证,对系统运行质量进行分析,并进行维护记录。对监控或维护中发现的问题及时处理,消除隐患,保障平台的稳定运行。

3.2 系统性能监控管理

运维团队通过综合监控系统等实施7*24a小时平台设备监控,发现告警,并进行处理,解决问题。使用综合监控系统对系统运行进行实时检查。对监控或维护中发现的问题及时处理,消除隐患,保障平台的稳定运行。

3.3 系统维护管理

故障处理

运维团队负责故障发现、故障分析、故障处理工作,在规定时间内,处理完成故障,同时负责调查故障原因,最后编写详细的《故障报告》,包括故障发生的起止时间、原因、现象、处理过程、处理结果和处理经验。如果故障设备或组件为第三方维保,值班工程师负责和第三方对接,迅速解决问题。

软件和补丁维护

操作系统级别的软件和补丁服务

  • 运维团队对于维保设备提供所有软件补丁,提供预警服务,对于软件的维护版本提供补丁,并按稳定性和安全性的要求,提供是否升级的建议,评估风险和制作实施方案。

  • 故障经工程师的分析表明它是由一个软件错误所引起的,那么运维团队需提供相应的软件版本和补丁。

  • 对于软件版本和补丁的安装,运维团队首先将确认是否可以在对应平台上进行装载。若确认可实施,运维团队则将提供补丁升级服务,升级前要配合相关应用方做好测试。

应急预案及演练

为加强风险管理意识,提高应急预案相关人员的应急处置能力,及时发现应急预案可能存在的问题,确保在紧急情况下,应急预案能够真正发挥作用,需要通过周期性的演习演练来不断检验应急体系应急预案的可靠性、有效性和可操作性。

应急预案的演习演练方式、演习演练频度等内容明确如下:

1、演练分为桌面演练和实战演练两种方式,每次演练都应该有相关技术人员全程参与。

2、定期桌面演练,定期实战演练;

3、每次演练结束之后应进行分析和总结,及时完成应急预案的更新、优化和完善。

协助第三方维护

在服务期内,运维团队将配合第三方或服务商进行系统的升级、替换、新部件(模块)安装等,并在实施完成后确认工作正常。

备份

为保证在系统崩溃或停止运行时能尽快恢复系统,将制定相关的数据备份制度。应针对不同系统制定备份方案,应包括备份方法、频率等。数据备份包括定期和不定期备份。重要数据应每月进行全备份和增量备份;不定期备份应该在数据变更后立即进行,更新前的备份按需要保存一定时间。

系统优化

对于巡检或日常维护过程中发现的系统隐患或系统不是处于满意状态,提供相关系统优化的报告。

对于运行情况跟踪,预防性诊断设备存在的隐患,提供系统优化建议,提供系统规范和流程的建议,提供系统优化概要。

硬件设备统计

运维团队将定期对参保设备进行统计。

质量分析报告

运维团队建立数据中心平台的质量分析报告。每月汇总设备运行质量、系统性能等指标,进行数据中心平台运行质量分析,排除质量隐患,不断提高网络运行质量和服务质量。

运维工程师应每周和每月对于数据中心在网系统运行情况作分析,数据采集、统计和分析系统设备的运行数据,形成系统运行周报和月报。

分析报告,包括优化设备运行的绩效,提高系统稳定性的建议,对于系统扩容和优化投资的建议,提供系统运行情况概要,系统中关键设备的运行情况分析,并能识别和解决潜在问题,做好预警,制定并实施相应的优化措施,并对于系统的扩容和项目投资提供建议报告。

3.4 系统配置与支持维护

运维团队的日常工作中,在系统配置和支持方面的工作内容如下:

  • 维护系统软硬件配置文档;

  • 负责系统用户管理,如增加、删除用户、重置用户密码、管理用户权限等;

  • 进行系统用户管理时必须遵循数据中心的账户命名规则及账户密码策略,并文档记录所有相关的系统变更;

  • 每月提交系统账户变更月报;

  • 配合第三方进行升级、安装系统,及时更新操作系统补丁,进行系统软件备份;

  • 根据运维报告及统计报表,每月制定维护作业计划,并提交日常维护报告;

3.5 系统容量管理

运维团队至少每半年进行一次对于每个服务器的系统容量监测的审核,并制定相应的容量规划,主要监测文件系统的空间、数据库的空间资源利用情况,分析资源利用趋势,并提供资源情况月报表。

文件系统空间管理

  • 定期检查文件系统的空间使用情况,根据业务发展需求和新业务的增加,制定合理的空间分配方案,新增、修改或删除空间。

  • 对文件系统空间的使用进行监控,发现空间使用不合理或需要清理的协调解决。

数据库空间管理

  • 应实时监测数据存储空间的使用情况,根据业务数据的数据量、数据结构以及增长速度,制定合适的数据存储和结构优化策略,动态增加新的空间以存放业务数据;

  • 定期检查数据存储空间的使用情况,根据实际情况规划增加新的空间,填写数据库空间新增/修改/删除申请表,经审核后实施,并更新数据库配置状况记录表;

3.6 巡检工作

除了依靠数据中心的监控软件,还要求运维团队对服务器、存储、操作系统、数据库、中间件等基础设施进行巡检,并编写巡检报告。通过巡检可以对当前系统的运行状况有一个详细的了解,对巡检中发现的问题可以及时采取预防性措施,降低故障发生的概率,提高系统的可靠性。

巡检工作需要检查以下几个方面:

  • 场地环境检查:包括机房的温度、湿度、通风及UPS工作状态等的检测;

  • 操作系统:检查补丁完整性,记录软件版本,以保证系统发挥最佳性能;

  • 外设检查:对网卡或HBA卡、磁盘驱动器的读写、磁带机的读写进行检测;

  • 网络设备检查:运行环境检查、LED控制面板、IOS版本信息、进程状态、内存利用率、接口状态、路由表状态、网络连通性测试;

  • 设备清洁:对相关设备进行维护保洁工作,使设备保持良好的运行状态;

  • 系统日志检查;

  • 文件系统检查、清理;

  • 系统配置检查;

  • 系统和数据备份检查;

  • 系统运行情况分析;

  • 系统总体性能评估。

1.机房环境日常检查内容

机房环境服务是为机房设备如小型机、网络设备和存储设备等提供一个安全可靠的物理环境,确保机房设备不会因为环境因素导致不能正常运行或损坏。

为了达到此目的,机房环境需具备以下标准:

  • 确保机房温度在24+2℃之间,最大温度变化率不超过10℃/小时;

  • 确保机房湿度在50+5%之间;

  • 确保机房电压在220V+5%之间,电压频率在50.5~49.5之间,瞬间变动电压不超过220V+/-15%,总谐波不高于5%;

  • 机房电源地线方面确保机房接地线与任何导线完全隔离及绝缘,接地线线径至少为3.5mm,系统接地电阻在电源插座连线与地线间不大于2欧姆,在电源输出座连线与地线间电压小于1V,在接地线的接地端测的接地电阻不大于1欧姆;

  • 确保机房为网络设备、空调、视频等提供独立的冗余双电源供应系统,杜绝电源公用现象,确保网络设备电源无隐患;

  • 确保机房整洁干净,避免机房在阳光直射之下;

  • 确保机房无线电杂波干扰低于0.5V/米;

2.服务器、存储、操作系统、数据库、中间件巡检及巡检报告内容

针对服务器、存储、操作系统、数据库、中间件等比较重要的组件,数据中心制定了按月巡检的计划,需要按照巡检报告的模板进行检查,巡检报告要涵盖以下内容:

3.7 定期服务报告

系统维护档案,详细记录数据中心相关的设备信息和项目管理信息。在日常运维中,服务报告和技术文档由运维团队的相关人员负责维护和更新。

系统维护档案将分为以下四个部分:

3.7.1 设备配置档案

  • 维护设备及软件清单、系统功能、详细配置信息及软件版本和设备PN号;

  • 设备位置、网络拓扑、设备连接拓扑及各种工程图纸;

  • 如果系统发生变更,如实施软件、补丁、微码升级或业务调整,同步更新配置档案;

  • 系统双机、备份设置和运行情况。

3.7.2 服务文档

  • 技术参数的配置文档;

  • 处理故障时的《故障处理报告》;

  • 每季度的《季度运维总结》;

  • 每次重大故障处理后发布《重大问题分析报告》;

  • 共享维护内容及其他技术资源整理知识库;

  • 每次巡检时的《巡检报告》;

  • 微码更新、性能分析及优化、机房搬迁等服务实施方案、专业服务报告和技术建议等。

3.7.3 服务总结

运维团队根据自身的工作内容,在每季度需要对自己的工作进行汇总,并生成《季度运维总结》。

报告中的具体内容包括:

  • 故障处理及备件更换情况汇总;

  • 设备状况分析及评价;

  • 人员出勤情况,工作量,或资源使用情况,包括第三方供应商服务情况;

  • 重大事件和变更情况;

  • 配置管理相关信息;

  • 趋势信息;

  • 下一步工作计划;

3.8 运行维护优化评估

(1) 建立基于数据中心的基础运维服务管理框架体系及运维团队,根据网络的现状提出整体安全规划,包括日常维护计划、安全风险控制计划、应急响应计划等

(2) 提供风险评估、灾难恢复、应急响应、安全培训服务并提供报告

(3) 安全检测

每季度定期对服务范围内的对网络设备、服务器操作系统、数据库系统、应用软件系统的安全策略和安全配置进行检查和测试,从中获得相关的信息、发现系统面临的威胁以及存在的安全性。

(4) 安全评估。

每季度对服务范围内的整体网络系统进行全面、统一的系统性的安全风险评估,识别和控制网络中的关键资产及可能会产生的安全风险,并对所发现的问题提供优化、改进建议。并根据评估的结果为关键资产建立应急响应预案以及细微调整其后安全维护服务所要监控的内容。

(5) 策略优化

根据安全评估的结果每半年对系统策略及网络系统进行优化设计,制定调整系统策略优化、网络拓扑优化、安全域规划与配置、IP规划、VLAN优化等策略,并根据实际情况调整与实施。

(6) 应急预案与演练

根据数据中心的现状,模拟实际灾难发生场景,提供各种应急预案,经过采购人讨论,协助采购人实施演练。

(7) 培训

运维服务期内,安排以运维管理、安全为主题的培训,数量为4~5人次,按要求制定相应的培训计划。

(8) 资料收集存档

参与机房运维涉及的专业第三方机构合同的起草、谈判,与采购人一起对第三方机构进行管理。整理收集涉及到的第三方合同,中间文档、过程记录,备查,按照采购人规定进行提交。

3.9 应急保障措施和组织

3.9.1 应急响应系统

运维团队在处理紧急情况和重大事项时,会启用应急指挥系统: 

接口人:应用系统下,各个相关方的固定接口人,一般为项目经理

运维团队:事故发生期间提供直接的技术咨询、指导服务,负责直接处理故障。

二线专家:严重事件由承保的第三方服务商或原厂商的二线专家最快速度到达现场处理事故。

3.9.2 应急响应过程

应急响应过程划分为四个主要阶段:应急准备、监测与预警、应急处置措施和总结改进。

a)应急准备阶段的工作包括:组建应急响应组织,确定应急响应制度,系统性识别运行维护服务对象及运行维护活动中可能出现的风险,定义应急事件级别,制定预案,开展培训和演练;

b)监测与预警阶段的工作包括:进行日常监测,及时发现应急事件并有效预警,进行核实和评估,以规定的策略和程序启动预案,并保持对应急事件的跟踪;

c)应急处置阶段的工作包括:采取必要的应急调度手段,基于预案开展故障排查与诊断,对故障进行有效、快速的处理与系统恢复,及时通报应急事件,提供持续性服务保障,进行结果评价,关闭事件;

d)总结改进阶段的工作包括:对应急事件发生原因、处理过程和结果进行总结分析,持续改进应急工作,完善信息系统。

3.9.3 制定应急保障预案及演练

为了应对业务系统可能出现的紧急故障,运维团队将定期模拟故障演练服务。

运维团队有一套整体的应急方案,以确保数据中心在系统发生突发事件或灾难情况下能够迅速恢复IT服务,从而保证系统业务的持续运行。根据普遍认可的最佳实践指导原则,IT应急和IT灾难恢复的定义应该是:

“计算机系统灾难是指任何造成计算机系统不能处理业务的时间超过了可容忍程度的事故。应急方案是指计算机系统灾难发生后,按照既定的应急恢复方案在一定时间内恢复系统运行和业务处理的过程。”

为了应对生产系统可能出现的紧急故障(重大、严重故障),数据中心将从事前预防和事后处理两个方面制定紧急故障应处理预案。

(A)事前预防:

 应急涉及到多个层面的配合,每方都需要指定专人负责在紧急故障发生时及时沟通

 数据中心专家支持团队进行系统风险评估,提出系统整改建议,制定紧急故障应急处理预案

 进行一定次数的实际演练,包括后备系统切换测试、备份数据还原测试

 对流程进行持续性跟踪,系统出现变更后,重新评估流程的有效性

(B)事后处理:

 响应时间:由工程师立即做出响应

 故障修复:由经验丰富的专家支持团队提供专人支持,包括搭建测试环境、远程和现场故障诊断和排除;同时启动紧急故障处理流程,按既定程序做应急处理


图片
图片

应急演练:

应急演练计划至少每季度一次进行测试和演练,以保证:

 计划内容能够反映当前的状况;

 计划的有效性和可操作性;

 应急演练人员熟悉应急恢复流程。

所有测试和演练的结果应当依据事先确定好的标准,来判断测试和演练是否成功。如:多长时间恢复服务,会出现多少问题,及问题的严重性等。在测试完成后应记录下结果,并根据需要对应急恢复计划进行修订。针对演练或测试过程中出现的问题和失败应该进行说明并体现在相应的改进计划中。

3.10 IT运维服务工具

3.10.1 运维监控平台

运维服务事件管理系统是支撑运维管理组织中各运维角色按照规定的运维事件流程开展运维活动的信息化系统。一方面,该系统要支持运维服务提供者对运维服务事件管理对象进行管理,以实现运维服务的能力;另一方面,要支持运维服务提供者按照商定的服务级别协议方便地向运维服务使用者提供运维服务;同时,要支持运维服务管理者对整个运维服务事件的考核、监督和评估。运维服务事件管理工具是构成运行管理体系不可缺少的元素,从被动管理向主动管理转化的重要部分,为整个运行管理体系的高效实施奠定了基础。

监控拓扑

当前数据中心采用了华胜运维监控平台,对数据中心设备进行监测。用户通过客户端登录华胜运维监控平台,查看所有被监控设备的运行情况。当前监控平台支持机房环境、网络设备、存储设备、服务器设备、系统和数据库等组件的监控,支持故障预警等服务。

图片

主机监控

为确保数据中心服务器高速、稳定运转,华胜运维监控平台从多个方面对主机服务器的硬件设备及操作系统进行监控管理和性能管理。它通过采集服务器的CPU、内存、硬盘、网卡等硬件的关键运行参数,以及软件和应用程序的进程、服务、端口等的运行状况,对系统日志进行分类扫描查询。通过数据采集和分析,华胜运维监控平台能够及时对影响用户服务器运行性能的故障事件发送报警,并采取相应的故障处理措施,保证服务器的正常安全运行。

Windows服务器监控

运维监控平台对服务器的监控支持Agent代理、SNMP和WMI非代理三大方式,方便不同用户对服务器全面监控的需求。运维监控平台服务器主要监测指标如下

图片


图片

Linux服务器监控

运维监控平台对Linux服务器的监控支持Agent代理、SNMP和SSH、Telnet非代理三大方式,方便不同用户对服务器全面监控的需求。运维监控平台Linux服务器主要监测指标如下

图片

网络设备监控

华胜运维监控平台可以从各个方面对数据中心的网络设备进行监测和管理,内容包括网络设备的可用性、设备性能、流量管理等等。华胜运维监控平台的网络设备管理系统支持的网络设备,包括各种类型的交换机、路由器、防火墙、VoIP网关设备和其他启用了SNMP协议的网络设备。

华胜运维监控平台监测对象主要包括网络设备(路由器、交换机、防火墙)的状态,如端口,路由器CPU负载等,支持Cisco、华为、港湾、Juniper等各主流厂家的路由器、交换机,支持Netscreen、Cisco、天融信等主流厂商的防火墙等网络安全设备。

 网络设备监控

 安全设备监控

不同类型设备,所监控的内容会有不同。

应用监控

华胜运维监控平台的应用监测模块可以全面智能的监测用户各种与应用相关的服务。华胜运维监控平台对各种数据库、中间件和WEB从应用可用性、系统资源占用和性能指标三个方面提供全面的监测管理策略,确保应用的运行正常。

 Oracle监控

 MS-SQL监控

监测器参数设置

华胜监测平台中所有监测器,都可以设置重试次数、超时等。

 监测器间隔:5秒 至 指定小时,如每10秒监测一次,或每5小时监测一次;

 监测器工作计划:可以设置7X24或5X8工作时间;

 错误后重试:任意重试次数,但建议不超过99;

 错误频率:监测器发生错误后,调整监测器的监测间隔,如CPU监测器原监测间隔为10分钟一次,发生错误后,监测间隔调整为1分钟一次;

 故障处理记录:针对监测器,记录故障处理的内容;

 阀值设置:最多可以设置8个阀值检测条件,每个阀值检测条件之间可以用:并、或的关系。

拓扑管理

自动发现能够自动识别设备类型,包括各种服务器类型、路由器、交换机、等等,以及它们之间的关系,并且自动将它们存储到公用对象库中对应的类中。

 故障告警管理

华胜运维监控平台故障管理系统是管理数据中心的设备、网络和业务所出现的故障;帮助网管人员采集、统计和分析来自网络各方面的报警信息和故障信息,准确预警、定位和解决网络中的故障。

 故障告警方式

华胜运维监控平台提供短信息、语音、声音、远程声音、邮件、脚本等多种方式及时发出警报。可以及时通企业的网管人员发现、定位和处理故障,让系统的管理从被动变为主动,可有效地预防故障发生,也可在故障发生时快速进行定位,及时处理好故障。

 报警控制台

关于对警报和故障的管理,华胜运维监控平台主要通过报警控制台来进行。华胜运维监控平台报警控制台包括四个方面:配置文件及接口数据、故障事件搜集、故障事件过滤、告警呈现。

用户权限设计

华胜运维监控平台支持精细的用户分级管理功能,用户按照权限分为超级管理员和一般管理员两类:超级管理员具备全部管理功能,可以为一般管理员配置不同的用户名、密码和权限;一般管理员具备部分管理功能(例如只读)。对一般管理员的功能限制主要从两方面来进行,一方面是管理对象权限设置,另一方面是管理功能权限设置,对于一般管理员的管理对象权限设置可以精确到对任意管理对象和管理对象权限的自由组合。

 

软件版本号规范

1. 软件版本阶段说明

o Base版: 此版本表示该软件仅仅是一个假页面链接,通常包括所有的功能和页面布局,但是页面中的功能都没有做完整的实现,只是做为整体网站的一个基础架构。

o Alpha版: 此版本表示该软件在此阶段主要是以实现软件功能为主,通常只在软件开发者内部交流,一般而言,该版本软件的Bug较多,需要继续修改。

o Beta版: 该版本相对于α版已有了很大的改进,消除了严重的错误,但还是存在着一些缺陷,需要经过多次测试来进一步消除,此版本主要的修改对像是软件的UI。

o RC版: 该版本已经相当成熟了,基本上不存在导致错误的BUG,与即将发行的正式版相差无几。

o Release版: 该版本意味“最终版本”,在前面版本的一系列测试版之后,终归会有一个正式版本,是最终交付用户使用的一个版本。该版本有时也称为标准版。一般情况下,Release不会以单词形式出现在软件封面上,取而代之的是符号(R)。

 

2. 版本命名规范

  软件版本号由四部分组成,第一个1为主版本号,第二个1为子版本号,第三个1为阶段版本号,第四部分为日期版本号加希腊字母版本号,希腊字母版本号共有5种,分别为:base、alpha、beta、RC、release。例如:1.1.1.051021_beta。

版本号定修改规则:

o 主版本号(1):当功能模块有较大的变动,比如增加多个模块或者整体架构发生变化。此版本号由项目决定是否修改。

o 子版本号(1):当功能有一定的增加或变化,比如增加了对权限控制、增加自定义视图等功能。此版本号由项目决定是否修改。

o 阶段版本号(1):一般是 Bug 修复或是一些小的变动,要经常发布修订版,时间间隔不限,修复一个严重的bug即可发布一个修订版。此版本号由项目经理决定是否修改。

o 日期版本号(051021):用于记录修改项目的当前日期,每天对项目的修改都需要更改日期版本号。此版本号由开发人员决定是否修改。

o 希腊字母版本号(beta):此版本号用于标注当前版本的软件处于哪个开发阶段,当软件进入到另一个阶段时需要修改此版本号。此版本号由项目决定是否修改。

 

3. 文件命名规范

 文件名称由四部分组成:第一部分为项目名称,第二部分为文件的描述,第三部分为当前软件的版本号,第四部分为文件阶段标识加文件后缀,例如:项目外包平台测试报告1.1.1.051021_beta_b.xls,此文件为项目外包平台的测试报告文档,版本号为:1.1.1.051021_beta。

  如果是同一版本同一阶段的文件修改过两次以上,则在阶段标识后面加以数字标识,每次修改数字加1,项目外包平台测试报告1.1.1.051021_beta_b1.xls

4.

  当有多人同时提交同一份文件时,可以在阶段标识的后面加入人名或缩写来区别,例如:项目外包平台测试报告1.1.1.051021_beta_b_lisg.xls。当此文件再次提交时也可以在人名或人名缩写的后面加入序号来区别,例如:项目外包平台测试报告1.1.1.051021_beta_b_LiuQi2.xls

5. 版本号的阶段标识

6. 软件的每个版本中包括11个阶段,详细阶段描述如下:

阶段名称

阶段标识

需求控制

a

设计阶段

b

编码阶段

c

单元测试

d

单元测试修改

e

集成测试

f

集成测试修改

g

系统测试

h

系统测试修改

i

验收测试

j

验收测试修改

k

 

 

转载自:http://blog.sina.com.cn/s/blog_60e2dbcf01012zer.html

 

PowerDesigner连接MySQL和逆向工程图

最近想梳理公司项目的表间关系,从项目后台管理系统的操作入手,以及代码的hibernate注解入手,都不算特别尽人意,于是最后还是鼓捣了一下PowerDesigner的逆向工程图,这样更直观一些。

想着以后不论项目切换或者接手的时候肯定是用得上的,所以在这里也记录一下。

1、MySQL数据库连接(JDBC方式)
JDBC的配置方式需要一些基础的环境和准备,但是也很简单,无非也就是JDK和mysql的连接jar包,这里不再展开阐述。
1.1 新建一个pdm,dbms选择mysql

1.2 Database – Connect  选择数据库连接

 

 

 1.3 配置连接信息

 

 

数据库连接这里是通过一个配置文件来获取连接信息的,首次的话因为没有,所以我们需要选择Configure进行配置。
1.4 填写配置信息

  

 

 

 

 

如图,选择添加数据库资源,出现如上,相关说明如下:
Connection profile name:JDBC配置文件名称,可随意填写
Directory:配置文件保存路径
Description:配置文件描述,可根据实际用途填写
Connection type:连接方式,这里我们选择JDBC
DBMS type:数据库类型,提供大部分主流数据库选择,我们选择MySQL
User name:登录数据库的用户名
JDBC driver class:指定驱动类,使用默认的com.mysql.jdbc.Driver
JDBC connection URL:连接URL,格式jdbc:mysql://ServerIP/Hostname:port/database
JDBC driver jar files:指定连接的jar包路径

 1.5 连接测试和配置保存

如果测试连接不通过,且出现 Non SQL Error : Could not load class com.mysql.jdbc.Drive 的错误,而指定的jar包没有问题,那么是因为PowerDesigner无法找到驱动所产生的。解决办法是配置系统的classpath路径,指定jar包路径就好了。

 

 

 成功连接后,我们一路确定下去把这个配置文件进行保存,最终你可以在你指定的文件夹(该目录没有限制,自定义一个目录即可,此处我是建立在安装文件下的一个userConf文件夹内)中看到这个保存好的文件:

 

 

2、从已有数据库中的表进行逆向工程图
2.1 菜单选择,从数据库更新模型

 

 

 

 

2.2 选择数据库连接配置文件

 

 

2.3 选择涉及的数据库和想要导出的表

 

 

2.4 大功告成

 

 

 

Docker容器进入的4种方式

在使用Docker创建了容器之后,大家比较关心的就是如何进入该容器了,其实进入Docker容器有好几多种方式,这里我们就讲一下常用的几种进入Docker容器的方法。

进入Docker容器比较常见的几种做法如下:

使用docker attach
使用SSH
使用nsenter
使用exec

一、使用docker attach进入Docker容器  Docker提供了attach命令来进入Docker容器。

我们使用docker ps查看到容器信息,接下来就使用docker attach进入容器

docker attach 44fc0f0582d9

 可以看到我们已经进入到该容器中了。

但在,使用该命令有一个问题。当多个窗口同时使用该命令进入该容器时,所有的窗口都会同步显示。如果有一个窗口阻塞了,那么其他窗口也无法再进行操作。
因为这个原因,所以docker attach命令不太适合于生产环境平时自己开发应用时可以使用该命令

二、使用SSH进入Docker容器

  在生产环境中排除了使用docker attach命令进入容器之后,相信大家第一个想到的就是ssh。在镜像(或容器)中安装SSH Server,这样就能保证多人进入

容器且相互之间不受干扰了,相信大家在当前的生产环境中(没有使用Docker的情况)也是这样做的。但是使用了Docker容器之后不建议使用ssh进入到Docker容

器内。关于为什么不建议使用,请参考如下文章:

为什么不需要在 Docker 容器中运行 sshd

三、使用nsenter进入Docker容器

在上面两种方式都不适合的情况下,还有一种比较方便的方法,即使用nsenter进入Docker容器。关于什么是nsenter请参考如下文章:

https://github.com/jpetazzo/nsenter

在了解了什么是nsenter之后,系统默认将我们需要的nsenter安装到主机中

如果没有安装的话,按下面步骤安装即可(注意是主机而非容器或镜像)

具体的安装命令如下:

$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz  
$ tar -xzvf util-linux-2.24.tar.gz  
$ cd util-linux-2.24/  
$ ./configure --without-ncurses  
$ make nsenter  
$ sudo cp nsenter /usr/local/bin  
安装好nsenter之后可以查看一下该命令的使用。

nsenter可以访问另一个进程的名称空间。所以为了连接到某个容器我们还需要获取该容器的第一个进程的PID。可以使用docker inspect命令来拿到该PID。

docker inspect命令使用如下:

$ sudo docker inspect --help   
inspect命令可以分层级显示一个镜像或容器的信息。比如我们当前有一个正在运行的容器

可以使用docker inspect来查看该容器的详细信息。

$ sudo docker inspect 44fc0f0582d9  

由其该信息非常多,此处只截取了其中一部分进行展示。如果要显示该容器第一个进行的PID可以使用如下方式

$ sudo docker inspect -f {{.State.Pid}} 44fc0f0582d9  

在拿到该进程PID之后我们就可以使用nsenter命令访问该容器了。

$ sudo nsenter --target 3326 --mount --uts --ipc --net --pid  
$ sudo nsenter --target 3326 --mount --uts --ipc --net --pid  
其中的3326即刚才拿到的进程的PID

  四、使用docker exec进入Docker容器

除了上面几种做法之外,docker在1.3.X版本之后还提供了一个新的命令exec用于进入容器,这种方式相对更简单一些,下面我们来看一下该命令的使用:

$ sudo docker exec --help   

接下来我们使用该命令进入一个已经在运行的容器

$ sudo docker ps  
$ sudo docker exec -it 775c7c9ee1e1 /bin/bash