0%

mysql> create database test; –创建一个叫test的库
mysql> create database test character set=utf8; –创建库的时候,指定非默认的字符集
mysql> alter database test character set=gbk; –修改一个库的字符集
mysql> drop database test; –删除test库
mysql> use test; –使用test库
mysql> create table emp (ename varchar(20),sex char(1),hiredate date,sal decimal(10,2),deptno tinyint(1)); –创建表
mysql> show create table emp; –查看创建表的参数,引擎和默认的字符集
mysql> alter table emp engine=memory; –修改表的引擎
mysql> alter table emp default charset=utf8; –修改表的字符集
mysql> drop table emp; –删除emp表
mysql> create table emp ( ename varchar(20), sex char(1), hiredate date, sal decimal(10,2), deptno tinyint(1)) engine=memory default charset=utf8; –也可以在创建表时直接指定非默认的引擎或字符集
mysql> create table dept (deptno tinyint(1),deptname varchar(30),location varchar(50)); –再创建一个部门表,注意deptno这一列和emp表的deptno列是对应的
–选择字符集的原则
1,如果应用要处理各种各样的文字,或者要发布到使用不同语言的国家或地区,就应该选择unicode字符集。对mysql来说,目前就是UTF-8
2,如果应用涉及已有数据的导入,就要充分考虑数据库字符集对已有数据的兼容性;假如已有数据是GBK,选择GB2312-80为数据库字符集,就很可能出现某些文字无法正确导入的问题
3,如果数据库只需要支持一般中文,数据量很大,性能要求也很高,那就应该选择双字节定长编码的中文字符集,如GBK。相对于UTF-8来说,GBK比较小,只占2个字节,相对于UTF-8汉字编码要3个字节来说,可以减少I/O,数据库cache以及网络传输时间,提高性能。
如果主要处理英文字符,仅有少量汉字数据,则选择UTF-8更好,因为GBK的西文字符编码都为2个字节,会造成很大不必要的开销。
4,如果数据库需要做大量的字符运算,如比较,排序等,选择定长字符集可能更好,因为定长字符集的处理速度要比变长字符集的处理速度快。
5,如果所有客户端程序都支持相同的字符集,应该优先选择此字符集作为数据库字符集,这样可以避免因字符集转换带来的性能开销和数据损失。
mysql可以支持多种字符集,在同一台服务器,同一个数据库甚至同一个表的不同字段都可以指定使用不同的字符集,相比oracle等其他数据库在同一个数据库上只能使用相同的字符集,mysql明显存在更大的灵活性。
mysql> show character set; –查看所有可用的字符集
mysql> alter table emp add column age tinyint(1); –增加一个列,默认增加到最后

mysql> alter table emp add column manager varchar(30) after hiredate; –在hiredate这列后面增加一列,使用after关键字

mysql> alter table emp add column manageraaaa varchar(30) first; –把一列加到最前面,使用first关键字
–first和after是mysql自己的SQL语法扩展,在oracle数据库里就没有这种功能,它需要使用select按需求的顺序给选取出来,再导入到新表,删除老表
–比如说加了一个age列,要把age列放到最前面,则需要select时把age列放在第一位,再创建成emp1表
mysql> create table emp1 as select age,ename,sex,hiredate,sal,deptno from emp ;
mysql> drop table emp; –删除emp表
mysql> rename table emp1 to emp; –再把emp1表重命名成emp

mysql> alter table emp modify manager varchar(40); –使用modify修改一列的数据类型

mysql> alter table emp change manager manager varchar(30); –使用change修改一列的数据类型

mysql> alter table emp change manager mana varchar(30); –修改列名要使用change去修改

–modify和change的区别,都可以修改数据类型,但change要写原列名;只有change可以修改列名,modify不可以

mysql> alter table emp drop manageraaaa; –删除某一列
练习:通过上面的命令,把emp表多加三列,成为下面的格式
+———–+—————+——+—–+———+——-+
| Field | Type | Null | Key | Default | Extra |
+———–+—————+——+—–+———+——-+
| empno | int(11) | YES | | NULL | |
| ename | varchar(20) | YES | | NULL | |
| sex | char(1) | YES | | NULL | |
| birthday | date | YES | | NULL | |
| hiredate | date | YES | | NULL | |
| sal | decimal(10,2) | YES | | NULL | |
| deptno | tinyint(1) | YES | | NULL | |
| managerno | int(11) | YES | | NULL | |
+———–+—————+——+—–+———+——-+
mysql> alter table emp add empno int first;

mysql> alter table emp add birthday date after sex;

mysql> alter table emp add managerno int;

mysql> truncate table emp; –截断表,清空了表内的所有数据,但是表的结构还在

例:简述 drop,delete,truncate的区别?

drop 可以删库,表等整个对象;delete和truncate只能删表里的数据

drop和truncate属于DDL,在事务控制里是不用commit提交的;delete属于DML,需要commit提交;

高水位线(high watermark)
比如100W行的一张表,用delete或truncate删完数据。delete水位线不下降,truncate下降。

mysql> insert into aaa.emp values (1,’boss’,’m’,’1964-08-08’,’1995-01-01’,’20000’,’1’,’1’)
–插入数据,注意在mysql里数字可以不用加引号,别的都加引号

mysql> insert into emp values
-> (1,’boss’,’m’,’1964-08-08’,’1995-01-01’,’20000’,’1’,’1’),
->(2,’zhangsan’,’m’,’1967-04-05’,’1995-04-11’,’15000’,’2’,’1’);
Query OK, 2 rows affected, 0 warning (0.02 sec)
Records: 2 Duplicates: 0 Warnings: 0
–一次插入多条记录

还可以插入特定的列(非所有列),那么没有插入的就成了空值(空值不是0,它做任何运算结果还是空值)

mysql> insert into emp (ename,sex) values (‘lisi’,’m’);
下面针对上面的新表结构,直接插入9列数据
insert into test.emp values (1,’boss’,’m’,’1964-08-08’,’1995-01-01’,’20000’,’1’,’1’),(2,’zhangsan’,’m’,’1967-04-05’,’1995-04-11’,’15000’,’2’,’1’),(3,’lisi’,’f’,’1973-01-28’,’1998-11-21’,’13000’,’3’,’1’),(4,’wangwu’,’f’,’1975-06-03’,’1999-12-12’,’12000’,’4’,’1’),(5,’maliu’,’m’,’1982-08-18’,’2001-07-03’,’8000’,’2’,’2’),(6,’tianqi’,’f’,’1983-02-15’,’2002-11-01’,’7000’,’2’,’2’),(7,’mark’,’m’,’1984-08-12’,’2003-10-02’,’6500’,’3’,’3’),(8,’john’,’m’,’1985-09-14’,’2005-04-03’,’6000’,’3’,’3’),(9,’mm’,’f’,’1990-06-08’,’2008-09-13’,’4000’,’4’,’4’);
mysql> select * from test.emp;
+——-+———-+——+————+————+———-+——–+———–+
| empno | ename | sex | birthday | hiredate | sal | deptno | managerno |
+——-+———-+——+————+————+———-+——–+———–+
| 1 | boss | m | 1964-08-08 | 1995-01-01 | 20000.00 | 1 | 1 |
| 2 | zhangsan | m | 1967-04-05 | 1995-04-11 | 15000.00 | 2 | 1 |
| 3 | lisi | f | 1973-01-28 | 1998-11-21 | 13000.00 | 3 | 1 |
| 4 | wangwu | f | 1975-06-03 | 1999-12-12 | 12000.00 | 4 | 1 |
| 5 | maliu | m | 1982-08-18 | 2001-07-03 | 8000.00 | 2 | 2 |
| 6 | tianqi | f | 1983-02-15 | 2002-11-01 | 7000.00 | 2 | 2 |
| 7 | mark | m | 1984-08-12 | 2003-10-02 | 6500.00 | 3 | 3 |
| 8 | john | m | 1985-09-14 | 2005-04-03 | 6000.00 | 3 | 3 |
| 9 | mm | f | 1990-06-08 | 2008-09-13 | 4000.00 | 4 | 4 |
+——-+———-+——+————+————+———-+——–+———–+
9 rows in set (0.00 sec)
把dept表也插入记录,方便下面的实验
mysql> insert into dept values
-> (1,’manager’,’beijing’),
-> (2,’it’,’shenzhen’),
-> (3,’sale’,’shanghai’),
-> (4,’services’,’guangzhou’);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> select * from dept;
+——–+———-+———–+
| deptno | deptname | location |
+——–+———-+———–+
| 1 | manager | beijing |
| 2 | it | shenzhen |
| 3 | sale | shanghai |
| 4 | services | guangzhou |
+——–+———-+———–+
4 rows in set (0.00 sec)

===============================================================
update

把wangwu性别改成m

mysql> update emp set sex=’m’ where ename=’wangwu’;

wangwu的工资加500

mysql> update emp set sal=sal+500 where ename=’wangwu’;

2号部门的工资涨10%

mysql> update emp set sal=sal+sal*0.1 where deptno=2;

mark由3号部门换成2号部门,同时工资加1000,上级管理者也改为2号部门的头

mysql> update emp set deptno=’2’ and sal=sal+1000 and managerno=2 where ename=’mark’; –错误写法

mysql> update emp set deptno=’2’,sal=sal+1000,managerno=2 where ename=’mark’; –正确写法
工资就john和mark涨10%,其它人不涨
mysql> update emp set sal=sal+sal*0.1 where ename=’john’ or ename=’mark’;

mysql> update emp set sal=sal+sal*0.1 where ename in (‘john’,’mark’);

工资都涨10%,john和mark犯错误,就他们不涨
mysql> update emp set sal=sal+sal*0.1 where ename!=’john’ and ename<>’mark’;

mysql> update emp set sal=sal+sal*0.1 where ename not in (‘john’,’mark’);

delete

delete from emp where xxxx;


DQL

select

mysql> select * from emp; –* 代表查看所有列

mysql> select ename,sal from emp; – 只查看其中几列

mysql> select distinct deptno from emp; –distinct 去除重复行
查询所有男员工的姓名和工资
mysql> select ename,sal from emp where sex=’m’;

查询所有工资大于8000的员工的所有信息
mysql> select * from emp where sal>8000;

查询所有工资在4000到8000之间的员工的所有信息(包含4000和8000的)

mysql> select * from emp where sal>=4000 and sal<=8000;
mysql> select * from emp where sal between 4000 and 8000;

查询入职时间在2001那年的员工的姓名和工资
mysql> select ename,sal from emp where year(hiredate)=2001;
mysql> select ename,sal from emp where substr(hiredate,1,4)=2001;
mysql> select ename,sal from emp where hiredate>’2000-12-31’ and hiredate<’2002-01-01’;
mysql> select ename,sal from emp where hiredate >= ‘2001-01-01’ and hiredate <= ‘2001-12-31’;
mysql> select ename,sal from emp where hiredate like ‘2001%’;

查询2002年之后(包括2002年)入职的,并且工资大于8000的员工姓名

mysql> select ename from emp where year(hiredate)>=2002 and sal>8000;

--------------------------
排序操作统计工资总额,最大工资,最小工资,平均工资
mysql> select * from emp order by sal; –以工资排序,默认升序排序
mysql> select * from emp order by sal asc; –加不加asc都是升序

mysql> select * from emp order by sal desc; –desc表示降序排序

mysql> select * from emp order by sex,sal;
–先按性别排,再按工资排。结果是女的都在一起,以工资从小到大排。男的都在一起,以工资从小到大排。
mysql> select * from emp order by sex desc,sal desc;

找出工资最低的三个人的姓名和工资
mysql> select ename,sal from emp order by sal limit 3;

找出工资最高的三个人的姓名和工资

mysql> select ename,sal from emp order by sal desc limit 3;

找出工资最低的女员工的姓名和工资

mysql> select ename,sal from emp where sex=’f’ order by sal limit 1;

找出工资从高到低第三到第五的人的姓名和工资

mysql> select * from emp order by sal desc limit 2,3;

聚合和分组操作:

mysql> select count(*) from emp; –统计记录条数

mysql> select count(distinct deptno) from emp;
+————————+
| count(distinct deptno) |
+————————+
| 4 |
+————————+
1 row in set (0.00 sec)

mysql> select count(distinct deptno) deptcount from emp; –别名
+———–+
| deptcount |
+———–+
| 4 |
+———–+

统计每个部门的人数
mysql> select deptno,count(*) from emp group by deptno;

mysql> select ename,deptno,count(*) from emp group by deptno;
–这种在mysql里可以查,但无意义,在oracle里属于错误语法。因为前面select的列名除了count(),max(),min(),avg(),sum()等外,别的列名都必须在group by里

统计男,女员工各有多少人
mysql> select sex,count(*) from emp group by sex;

统计每个部门里男女员工各有多少个

mysql> select deptno,sex,count(*) from emp group by deptno,sex;

查找部门人数大于2的部门号和人数

mysql> select deptno,count() from emp group by deptno having count()>2;
求每个部门的工资总额,最大工资,最小工资,平均工资
mysql> select deptno,sum(sal),max(sal),min(sal),avg(sal) from emp group by deptno;

统计工资总额,最大工资,最小工资,平均工资

mysql> select sum(sal),max(sal),min(sal),avg(sal) from emp;

表链接(多表查询)
查出员工姓名和其对应的工资,部门名,部门所在地,并显示

mysql> select ename,sal,deptname,location from emp,dept where emp.deptno=dept.deptno;

mysql> select ename,sal,deptname,location from emp e,dept d where e.deptno=d.deptno;

------------------------

子查询:
查出比wangwu工资高的人的姓名和工资

mysql> select ename,sal from emp where sal>(select sal from emp where ename=’wangwu’);


DCL

grant 授权

mysql> grant select,insert on aaa.emp to ‘aa‘@’localhost’ identified by ‘123’; –授权使aa@localhost用户,对aaa库的emp表拥有select和insert权限
mysql> flush privileges; –刷新权限

mysql> revoke select on aaa.emp from ‘aa‘@’localhost’; –回收aa@localhost用户对aaa库的emp的select权限
mysql> flush privileges;

远程授权

服务端
mysql> grant all on . to ‘aa‘@’%’ identified by ‘123’; –all代表所有权限,*.*代表所有库的所有表 %代表所有IP
mysql> flush privileges;

客户端

[root@li ~]# /usr/local/mysql/bin/mysql -u aa -h 10.1.1.35 -p123 -P 3307

-p 参数表示密码,-P参数表示端口 ,如果是使用默认的3306就不用改端口


nginx

nginx的配置中不支持if条件的逻辑与&& 逻辑或|| 运算 ,而且不支持if的嵌套语法,否则会报下面的错误:nginx: [emerg] invalid condition。
我们可以用变量的方式来间接实现。

要实现的语句:

if ($arg_unitid = 42012 && $uri ~/thumb/){
 echo "www.ttlsa.com";
}

如果按照这样来配置,就会报nginx: [emerg] invalid condition错误。

如果按照这样来配置,就会报nginx: [emerg] invalid condition错误。

可以这么来实现,如下所示:

set $flag 0;
if ($uri ~ ^/thumb/[0-9]+_160.jpg$){
 set $flag "${flag}1";
}
if ($arg_unitid = 42012){
 set $flag "${flag}1";
}
if ($flag = "011"){
 echo "www.ttlsa.com";
}

原文地址: http://www.ttlsa.com/html/3876.html

SSL双向认证

1.安装nginx

rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm

yum install nginx

2.配置openssl

vim /etc/pki/tls/openssl.cnf
[ req_distinguished_name ]
countryName                     = Country Name(2 letter code)
countryName_default             = CN
countryName_min                 = 2
countryName_max                 = 2
stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = ZJ
localityName                    = Locality Name (eg, city)
localityName_default            = HZ
0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = Tech
organizationalUnitName          = Organizational Unit Name (eg, section)
organizationalUnitName_default  = Org

确保以上字段在证书,服务端证书,客户端证书一致。

创建证书的私钥
cd /etc/pki/CA/private
umask 077
openssl genrsa -out cakey.pem 2048
生成自签证书
cd /etc/pki/CA/
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3655
PS:填坑
openssl ca -in nginx.csr -out nginx.crt -days 3650
Using configuration from /etc/pki/tls/openssl.cnf
unable to load number from /etc/pki/CA/serial
error while loading serial number
140311870949192:error:0D066096:asn1 encoding     routines:a2i_ASN1_INTEGER:short line:f_int.c:215:

生成过程中遇到了该错误,用一下代码解决:

cd /etc/pki/CA
echo "00" >serial
cat serial
创建服务器证书
mask 077
openssl genrsa -out nginx.key 1024
openssl req -new -key nginx.key -out nginx.csr
openssl ca -in nginx.csr -out nginx.crt -days 3650
创建客户端证书
umask 077
openssl genrsa -out client.key 1024
openssl req -new -key client.key -out client.csr
openssl ca -in client.csr -out client.crt -days 3650
PS:填坑
failed to update database
TXT_DB error number 2

该错误是因为多次生成证书造成/etc/pki/CA/index.txt存在

rm -rf /etc/pki/CA/index.txt
touch /etc/pki/CA/index.txt
问题解决

生成完成后进行证书类型转换

openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
配置nginx服务器验证
ssl on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_verify_client on; ##双向认证
ssl_prefer_server_ciphers on;
ssl_session_timeout 5m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_certificate      nginx.crt;
ssl_certificate_key  nginx.key;
ssl_client_certificate /etc/pki/CA/cacert.pem;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
配置本地证书
client.p12下载到本地导入即可。
原文链接:http://www.yunops.top/2015/07/10/nginx%E9%85%8D%E7%BD%AESSL%E5%8F%8C%E5%90%91%E8%AE%A4%E8%AF%81/

个人VPS上搭建邮件服务器比较繁琐,还容易被当做垃圾邮件服务器列入黑名单。

简单的方法就是可以配置SMTP通过Gmail或者QQ邮箱发送邮件。

postfix

本站使用的服务器是CentOS 6.5的,在上面配置了postfix+mailx,针对QQ邮箱SMTP非加密认证方式很简单,网上随便搜一下都有大堆教程。由于服务器放在国外,不能了解机房的真正环境,对非加密方式的信息传输很容易被其他服务器sniff到密码和邮件内容,当然在国内也是,配置SMTP最好是使用SSL加密(Ps:本人曾经遇到sniff到FTP密码的情况,因此强烈建议服务器上涉及密码的都用SSL传输)。

 

【postfix+mailx+QQ邮箱】CentOS配置方法:

 

1、不管有没有先卸载掉sendmail吧,并安装postfix+mailx

#卸载sendmail
service sendmail stop
chkconfig sendmail off
yum remove sendmail
#安装postfix mailx和sasl需要的包
yum install postfix mailx cyrus-sasl-plain

 

2、配置QQ邮箱SMTP账号信息

先看下QQ邮箱帮助,SSL端口可用465或者587

如何设置POP3/SMTP的SSL加密方式?
使用SSL的通用配置如下:
接收邮件服务器:pop.qq.com,使用SSL,端口号995
发送邮件服务器:smtp.qq.com,使用SSL,端口号465或587

 

接着创建密码配置文件 /etc/postfix/sasl_passwd  账号密码用分号:隔开

echo "[smtp.qq.com]:587    [email protected]:xxxxxxxxx" > /etc/postfix/sasl_passwd

 

密码是明文存储的,通过postmap创建hash加密文件sasl_passwd.db

最后测试没问题就可以删除sasl_passwd

postmap hash:/etc/postfix/sasl_passwd

 

3、创建ca证书,配置main.cf

#进入certs目录,先修改创建的证书时间,默认有效期只有一年,改成10年先

cd /etc/ssl/certs/
vi Makefile

找到里面所有的 -days 365 改为 -days 3650 也可以随便定个时间

保存退出后执行make

#创建证书

make server.pem

 

然后出现填写地区信息

[root@localhost certs]# make server.pem
umask 77 ; \
PEM1=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
PEM2=`/bin/mktemp /tmp/openssl.XXXXXX` ; \
/usr/bin/openssl req -utf8 -newkey rsa:2048 -keyout $PEM1 -nodes -x509 -days 3650 -out $PEM2 -set_serial 0 ; \
cat $PEM1 >  server.pem ; \
echo ""    >> server.pem ; \
cat $PEM2 >> server.pem ; \
rm -f $PEM1 $PEM2
Generating a 2048 bit RSA private key
............+++
..........................+++
writing new private key to '/tmp/openssl.hZa44C'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:GUANGDONG
Locality Name (eg, city) [Default City]:SHENZHEN
Organization Name (eg, company) [Default Company Ltd]:TENCENT
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

 

创建完成后会生成server.pem

#移动到/etc/postfix/目录
mv server.pem /etc/postfix/

 

重要:配置 generic 替换系统发信人,不然当你以root用户执行mailx的时候,发信人将是root@qq.com

这当然是不可能被腾讯允许的,会报错误(mail from address must be same as authorization user) 如下:

Sep 21 07:07:01 WEBSERVER postfix/qmgr[9086]: 43BD14953: from=<[email protected]>, size=1363, nrcpt=1 (queue active)
Sep 21 07:07:02 WEBSERVER postfix/smtp[9102]: 43BD14953: to=<[email protected]>, relay=smtp.qq.com[163.177.65.157]:587, delay=1, delays=0.02/0.03/0.91/0.08, dsn=5.0.0, status=bounced (host smtp.qq.com[163.177.65.157] said: 501 mail from address must be same as authorization user (in reply to MAIL FROM command))

 

需要在/etc/postfix/generic下添加账号映射,其他的服务器账号同理都要添加上。

echo '[email protected]    [email protected]' >>/etc/postfix/generic
#并生成generic.db文件
postmap /etc/postfix/generic

 

然后配置main.cf,备份原文件,然后清空main.cf,替换如下:

mydomain = qq.com
myorigin = $mydomain
myhostname = $mydomain
mydestination = $mydomain
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
relayhost = [smtp.qq.com]:587
smtp_use_tls = yes
smtp_tls_CAfile = /etc/postfix/server.pem
smtp_generic_maps = hash:/etc/postfix/generic
smtp_sasl_auth_enable = yes
smtp_sasl_security_options = noanonymous
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

 

 

4、先再开一个终端,实时查看maillog发送日志

tail -f /var/log/maillog

 

最后重启postfix,发送测试邮件

service postfix restart
#测试发送,最好先测试发送到其他域的邮件,例如163.com
echo 'This is a test mail' | mail -s 'This is a test mail' [email protected]

 

如果按照这个步骤来就可以正常发送成功失败的话看看错误日志,用Goolge搜,国内信息太少

 

最后的最后,测试没问题就把明文保存的邮箱密码文件删掉吧!

rm -f /etc/postfix/sasl_passwd

 

文章参考:

https://charlesauer.net/tutorials/centos/postfix-as-gmail-relay-centos.php

http://stackoverflow.com/questions/9538817/how-to-change-default-email-address-for-postfix

http://www.zoneminder.com/wiki/index.php/How_to_install_and_configure_Postfix_as_a_Gmail_SMTP_relay_for_ZoneMinder_email_filter_events.

 

原文链接:http://www.jslink.org/linux/centos-postfix-mailx-qq-smtp-sendmail.html

mysql

SAE自带的SaeMail限制比较多,不但附件有1M的大小限制,而且无法直接将zip文件发送邮箱,而通过第三方的类来发邮件,可以很好的解决这两个问题。

[PHP] 简易的SMTP邮件发送类

/*
    简易的SMTP发送邮件类,代码比较少,有助于学习SMTP协议,
    可以带附件,支持需要验证的SMTP服务器(目前的SMTP基本都需要验证)
    编写: chenall
    时间: 2012-12-04
    网址: http://chenall.net/post/cs_smtp/
    修订记录:
        2012-12-08
            添加AddURL函数,可以直接从某个网址上下载文件并作为附件发送。
            修正由于发送人和接收人邮件地址没有使用"<>"126邮箱SMTP无法使用的问题。
        2012-12-06
            添加reset函数,重置连接,这样可以发送多个邮件。
        2012-12-05
           发送附件的代码整合到send函数中,减少变量的使用,快速输出,节省内存占用;
        2012-12-04
           第一个版本

    使用方法:

        1\. 初始化:连接到服务器(默认是QQ邮箱)
           $mail = new cs_smtp('smtp.qq.com',25)
           if ($mail->errstr) //如果连接出错
               die($mail->errstr;
        2\. 登录到服务器验证,如果失败返回FALSE;
           if (!$mail->login('USERNAME','PASSWORD'))
                die($mail->errstr;
        3\. 添加附件如果不指定name自动从指定的文件中取文件名
           $mail->AddFile($file,$name) //服务器上的文件,可以指定文件名;
        4\. 发送邮件
            $mail->send($to,$subject,$body)
            $to 收件人,多个使用','分隔
            $subject 邮件主题,可选。
            $body  邮件主体内容,可选
*/
class cs_smtp
{
    private $CRLF = "\r\n";
    private $from;
    private $smtp = null;
    private $attach = array();
    public $debug = true;//调试开关
    public $errstr = '';

    function __construct($host='smtp.qq.com',$port = 25) {
        if (empty($host))
            die('SMTP服务器未指定!');
        $this->smtp = fsockopen($host,$port,$errno,$errstr,5);
        if (empty($this->smtp))
        {
            $this->errstr = '错误'.$errno.':'.$errstr;
            return;
        }
        $this->smtp_log(fread($this->smtp, 515));
        if (intval($this->smtp_cmd('EHLO '.$host)) != 250 && intval($this->smtp_cmd('HELO '.$host)))
            return $this->errstr = '服务器不支持!';
        $this->errstr = '';
    }

    private function AttachURL($url,$name)
    {
        $info = parse_url($url);
        isset($info['port']) || $info['port'] = 80;
        isset($info['path']) || $info['path'] = '/';
        isset($info['query']) || $info['query'] = '';
        $down = fsockopen($info['host'],$info['port'],$errno,$errstr,5);
        if (!$down)
            return false;
        $out = "GET ".$info['path'].'?'.$info['query']." HTTP/1.1\r\n";
        $out .="Host: ".$info['host']."\r\n";
        $out .= "Connection: Close\r\n\r\n";
        fwrite($down, $out);
        $filesize = 0;
        while (!feof($down)) {
            $a = fgets($down,515);
            if ($a == "\r\n")
                break;
            $a = explode(':',$a);
            if (strcasecmp($a[0],'Content-Length') == 0)
                $filesize = intval($a[1]);
        }
        $sendsize = 0;
        echo "TotalSize: ".$filesize."\r\n";
        $i = 0;
        while (!feof($down)) {
            $data = fread($down,0x2000);
            $sendsize += strlen($data);
            if ($filesize)
            {
                echo "$i Send:".$sendsize."\r";
                ob_flush();
                flush();
            }
            ++$i;
            fwrite($this->smtp,chunk_split(base64_encode($data)));
        }
        echo "\r\n";
        fclose($down);
        return ($filesize>0)?$filesize==$sendsize:true;
    }

    function __destruct()
    {
        if ($this->smtp)
            $this->smtp_cmd('QUIT');//发送退出命令
    }

    private function smtp_log($msg)//即时输出调试使用
    {
        if ($this->debug == false)
            return;
        echo $msg."\r\n";
        ob_flush();
        flush();
    }

    function reset()
    {
        $this->attach = null;
        $this->smtp_cmd('RSET');
    }

    function smtp_cmd($msg)//SMTP命令发送和收收
    {
        fputs($this->smtp,$msg.$this->CRLF);
        $this->smtp_log('SEND:'. substr($msg,0,80));
        $res = fread($this->smtp, 515);
        $this->smtp_log($res);
        $this->errstr = $res;
        return $res;
    }

    function AddURL($url,$name)
    {
        $this->attach[$name] = $url;
    }

    function AddFile($file,$name = '')//添加文件附件
    {
        if (file_exists($file))
        {
            if (!empty($name))
                return $this->attach[$name] = $file;
            $fn = pathinfo($file);
            return $this->attach[$fn['basename']] = $file;
        }
        return false;
    }

    function send($to,$subject='',$body = '')
    {
        $this->smtp_cmd("MAIL FROM: <".$this->from.'>');
        $mailto = explode(',',$to);
        foreach($mailto as $email_to)
            $this->smtp_cmd("RCPT TO: <".$email_to.">");
        if (intval($this->smtp_cmd("DATA")) != 354)//正确的返回必须是354
            return false;
        fwrite($this->smtp,"To:$to\nFrom: ".$this->from."\nSubject: $subject\n");

        $boundary = uniqid("--BY_CHENALL_",true);
        $headers = "MIME-Version: 1.0".$this->CRLF;
        $headers .= "From: <".$this->from.">".$this->CRLF;
        $headers .= "Content-type: multipart/mixed; boundary= $boundary\n\n".$this->CRLF;//headers结束要至少两个换行
        fwrite($this->smtp,$headers);

        $msg = "--$boundary\nContent-Type: text/html;charset=\"ISO-8859-1\"\nContent-Transfer-Encoding: base64\n\n";
        $msg .= chunk_split(base64_encode($body));
        fwrite($this->smtp,$msg);
        $files = '';
        $errinfo = '';
        foreach($this->attach as $name=>$file)
        {
            $files .= $name;
            $msg = "--$boundary\n--$boundary\n";
            $msg .= "Content-Type: application/octet-stream; name=\"".$name."\"\n";
            $msg .= "Content-Disposition: attachment; filename=\"".$name."\"\n";
            $msg .= "Content-transfer-encoding: base64\n\n";
            fwrite($this->smtp,$msg);
            if (substr($file,4,1) == ':')//URL like http:///file://
            {
                if (!$this->AttachURL($file,$name))
                    $errinfo .= '文件下载错误:'.$name.",文件可能是错误的\r\n$file";
            }
            else
                fwrite($this->smtp,chunk_split(base64_encode(file_get_contents($file))));//使用BASE64编码,再用chunk_split大卸八块(每行76个字符)
        }
        if (!empty($errinfo))
        {
            $msg = "--$boundary\n--$boundary\n";
            $msg .= "Content-Type: application/octet-stream; name=Error.log\n";
            $msg .= "Content-Disposition: attachment; filename=Error.log\n";
            $msg .= "Content-transfer-encoding: base64\n\n";
            fwrite($this->smtp,$msg);
            fwrite($this->smtp,chunk_split(base64_encode($errinfo)));
        }
        return intval($this->smtp_cmd("--$boundary--\n\r\n.")) == 250;//结束DATA发送,服务器会返回执行结果,如果代码不是250则出错。
    }

    function login($su,$sp)
    {
        if (empty($this->smtp))
            return false;
        $res = $this->smtp_cmd("AUTH LOGIN");
        if (intval($res)>400)
            return !$this->errstr = $res;
        $res = $this->smtp_cmd(base64_encode($su));
        if (intval($res)>400)
            return !$this->errstr = $res;
        $res = $this->smtp_cmd(base64_encode($sp));
        if (intval($res)>400)
            return !$this->errstr = $res;
        $this->from = $su;
        return true;
    }
}

完善后的代码共有4个文件,比较多,就不贴源文件了,直接下载吧。

[Download](https://img.fairydevil.com/2014/12/db_backup.zip)

click to begin

6K db_backup.zip

将下载后将文件夹放到代码路径下(文件夹名字可以自由修改),然后修改里面db_config.php中的配置,主要是邮箱和一些备份信息的设定;接着在网站代码根目录的config.yaml文件中添加一个cron任务,让备份可以自动定时执行。可以根据自己的需要设计,具体语法可以参考官网的文档。我的设置如下:
handle:
     - passwdaccess:  if(path ~ "db_backup/db_callback.php") passwd "user:passwd"
cron:  
     - description: SAE database backup
       url: db_backup/db_callback.php
       schedule: every day of month 04:00
       login: user@passwd
这样,在每天凌晨的4点就会进行自动备份。 OK,完工,去Storage看看吧,所有的备份数据均在那里,是不是心里踏实了许多。 (温馨提示:目前DeferredJob每天只能执行10次)

mysql

下面讲一下怎么使用SAE平台的Cron服务进行数据自动备份吧,数据无价,人的精力时间有限,现在希望的都是一切自动化。所以,首先想到的是Cron服务,可以按设定的时间规则自动进行相关任务。然后,再结合官方推荐使用的DeferredJob服务进行数据库备份,自然就解决问题了。可以新建一个php文件,如命名为:db_callback.php,使用DeferredJob进行数据导出,我的设置如下:
  /**  
  *  使用DeferredJob服务对数据库进行备份  
  *  结合Cron服务,实现定时备份  
  *  
  *  函数原型:  addTask($tasktype,$dbtype,$stor_domain,$stor_filename,$dbname,$tbname,$callback)  
  *  https://fairydevil.com/sae-scheduled-backup-database/  
  */  

$stor_domain = “yovisun”;//Storage的存放域
$file_path = “/db_backup/“;//文件路径
$file_name = date(‘YmdHis’).”.sql.zip”;//以当前的时间日期为文件名
$stor_filename = $file_path .$file_name;//完整的文件名(含路径)
$dbname = SAE_MYSQL_DB; //数据库名

$dj = new SaeDeferredJob();
$taskID = $dj->addTask(“export”, “mysql”, $stor_domain, $stor_filename, $dbname, null, null);
if($taskID===false){
var_dump($dj->errno(), $dj->errmsg());
}else{
var_dump($taskID);
}


这样就可以进行数据的导出,当然,请先创建相应的Storage,保证目录正确。接下来就是在config.yaml文件中设置Cron任务,可以根据自己的需要设计,具体语法可以参考官网的文档。我的设置如下:

handle:
     - passwdaccess:  if(path ~ "db_backup/db_callback.php") passwd "user:passwd"
cron:  
     - description: SAE database backup
       url: db_backup/db_callback.php
       schedule: every day of month 04:00
       login: user@passwd

这样,在每天凌晨的4点就会进行自动备份。
OK,完工,去Storage看看吧,所有的备份数据均在那里,是不是心里踏实了许多。
(温馨提示:目前DeferredJob每天只能执行10次)

Windows 7 下使用成功。
Youtube 使用了adaptive streaming。导致下载不了完整的 1080p 影片。

1. 首先上: http://en.savefrom.net/, 把视频音频下载下来。
2. 我把音频命名为 “audio.mp4” ,视频命名为 “video.mp4”
3. 上 http://ffmpeg.zeranoe.com/builds/下载ffmpeg,注意对应的版本.
4. 解压, 我放到D 盘。
5. 同时移动 audio.mp4 和 video.mp4 到 ffmpeg 文件夹.
6. 打开cmd,我以管理员身份运行。
现在分流音频.
D:>ffmpeg -i audio.mp4 -acodec copy -vn audio1.mp4
分流视频
D:>ffmpeg -i video.mp4 -vcodec copy -an video1.mp4
混流.
D:>ffmpeg -i video1.mp4 -i audio1.mp4 -vcodec copy -acodec copy final.mp4

ffmpeg

然后就会多一个文件final.mp4 了。试试看能不能播

这里以Win7+Chrome浏览器为例进行配置。

下载所需软件

您需要下载并安装下面的软件,如果您已经完成了这些操作可以跳到下一步骤。

SwitchySharp+plink(MyEnTunnel)

为Chrome安装 SwitchySharp 浏览器扩展

(下面的操作需要连接上VPN才能顺利进行)

进入“Chrome 网上应用店”,搜索 SwitchySharp,点击“+免费”进行下载并安装。

Chrome_SwitchySharp

安装完成自动显示配置界面,根据下图进行设置,然后点击“保存”

SwitchySharp

进入“切换规则”选项,在“规则列表URL”里填入
http://autoproxy-gfwlist.googlecode.com/svn/trunk/gfwlist.txt
选择“情景模式”为 devpn,点击“立即更新列表”按钮进行更新,最后点击“保存”。

SwitchySharp

好了,到止不需要VPN连接了,请断开VPN进行下面的操作。

MyEnTunnel 配置

按下图填写完成后点击“保存”,然后点击“连接”。

MyEnTunnel

当连接成功后, 系统托盘MyEnTunne的图标会由黄色变为绿色,点击”隐藏”,将它隐藏到系统托盘,这样不会占用您的任务栏。

命令行plink命令取代MyEnTunnel

MyEnTunnel是集成了plink命令的图形软件,懂plink命令的完全可以抛弃。

打开CMD命令提示符

D:\plink.exe -C -N -D 127.0.0.1:7070 -P 22 user@IP_address -pw passwd

当然你可以做一个proxy.bat的批处理文件

:master
D:\plink.exe -C -N -D 127.0.0.1:7070 -P 22 user@IP_address -pw passwd
goto master

什么?命令窗口很讨厌?好吧教你怎么解决,做一个proxy.vbe文件代码如下:

set ws=wscript.createobject("wscript.shell")
ws.run "D:\proxy.bat /start",0

设置 DNS,防止 DNS 污染

在首选 DNS 服务器中填写 8.8.8.8,备用 DNS 服务器中填写 8.8.4.4

SwitchySharp的使用就不说啦。