imeilige 发布的文章

本文基于:CentOS release 6.5 (Final)

注意SMTP使用默认端口25和加密端口465在配置上的区别

安装

yum -y install mailx

配置发送人信息

vim /etc/mail.rc 在最后增加:

set from=yourEmailAddress
set smtp=smtpAddress
set smtp-auth-user=yourEmailAddress
set smtp-auth-password=youPassword
set smtp-auth=login

使用三种方式发送邮件

  • 命令行: mail -s "theme" addressee,回车后输入内容按Ctrl+D发送邮件.
  • 管道符: echo "mail main content" | mail -s "theme" addressee
  • 文件内容作为邮件内容: mail -s "theme" addressee < /tmp/t.txt

thme是邮件标题,addressee收件人地址


在搜索CentOS上发送邮件时,大部分都是上面的流程,的确在部分机器是测试成功的,唯独ECS不成功,后来了解到ECS默认关闭25端口。


使用SSL的方式发送邮件

  • 修改/etc/mail.rc增加如下关于SSL的配置
    set nss-config-dir=/etc/mail.rc_ssl.crt
    set smtp-user-starttls
    set ssl-verify=ignore
  • 修改 set smtp=smtps://xxxx.xxxx:465
  • /etc/mail.rc_ssl.crt目录下增加Firefox浏览器*.db文件(cert8.db、key3.db、secmod.db)以支持SSL的方式发送邮件

如果你的电脑上装有Firefox,windows可以在 %userProfile%\AppData\Roaming\Mozilla\Firefox\Profiles\xxx.default,Linux~/.mozilla/firefox/xxx.default目录下获取*.db文件,或者直接从这类下载:https://dn-zhangguoli.qbox.me/mail.rc_ssl.crt.zip

  • 发送邮件,注意增加 -v 参数,否则报错.echo "email main content" | mail -v -s "theme" addressee

需求:自动备份网站数据文件到七牛

    os      : CentOS release 6.5 (Final)
    website : /opt/website
    MySQL   : /opt/mysql
    backup  : /opt/backup
    qshell  : /opt/qshell

备份网站文件

vim /opt/website.sh

#!/bin/sh
# tar /opt/website to /opt/backup/website

mkdir -p /opt/backup/website
t=`date +"%Y%m%d_%H%M%s"`
tar -zcvf /opt/backup/website/$t.tar.gz /opt/website

chmod u+x website.sh

备份MySQL文件

vim /opt/mysql.sh

#!/bin/bash

# use mysqldump backup mysql to /opt/backup/mysql

mkdir -p /opt/backup/mysql
t=`date +%Y%m%d_%H%M%S`
/opt/mysql/bin/mysqldump -P port -u userName -ppassword database > /opt/backup/mysql/$t.sql

port是MySQL端口,默认3306,userName是MySQL用户名,password是密码,database是要备份的数据库
因为密码是直接明文写在脚本中的,执行的时候会提示Using a password on the command line interface can be insecure.

chmod u+x mysql.sh

上传到七牛

qshell说明文档 : https://developer.qiniu.com/kodo/tools/1302/qshell
dircache说明文档:https://github.com/qiniu/qshell/blob/master/docs/dircache.md
qupload说明文档 :https://github.com/qiniu/qshell/blob/master/docs/qupload.md

  • 注册 七牛 账号并登录
  • 个人中心->密钥管理,创建密钥(AccessKey/SecretKey)
  • 选择自己的平台下载qshell并重命名为qshell,此处下载linux x64:
    wget https://dn-devtools.qbox.me/2.1.5/qshell-linux-x64
  • 设置密钥: ./qshell account AccessKeyValus SecretKeyValues
  • 生成要上传文件的列表upload.list.txt:vim /opt/qshell/cache.sh
    #!/bin/bash

    # auto create dircache upload.list.txt

    /opt/qshell/qshell dircache /opt/backup /opt/qshell/upload.list.txt
  • chmod u+x cache.sh
  • 配置qupload的支持文件: vim /opt/qshell/upload.conf
    {
      "src_dir" : "/opt/backup",
      "bucket" : "xxx",
      "log_file": "/opt/qshell/upload.log",
      "file_list": "/opt/qshell/upload.list.txt",
      "rescan_local": true,
      "check_exists": true
}
  • 使用qshell上传:vim /opt/qshell/qsyn.sh
    #!/bin/bash

    # syn /opt/backup/ to qiniu bucket/xxx

    /opt/qshell/qshell qupload /opt/qshell/upload.conf                                                        
  • chmod u+x qsyn.sh

添加定时任务

crontab -e

00 02 * * *  /opt/website.sh
05 02 * * *  /opt/mysql.sh
10 02 * * *  /opt/qshell/cache.sh
15 02 * * *  /opt/qshell/qsyn.sh

系统会在早上2点之后陆续执行上述任务将/opt/backup下的文件上传到七牛空间。

OAuth2.0是一个开放授权(open authorization)标准,允许用户让第三方应用获取其在某一另外网站的授权码,而无需提供给第三方应用在某网站的账号与密码。

OAuth2.0授权流程

假设第三方应用为zhangguoli.cn,服务器提供商为example.com/,授权服务器、认证服务器和资源服务器可以是一个服务器。

- 阅读剩余部分 -

CentOS release 6.5 (Final)
Oracle Release 11.2.0.4.0

  • 使用ssh连接到服务器
  • 切换到Oracle用户: su - oracle
  • 连接到Oracle:sqlplus /nolog
  • 使用管理员身份登录数据库: conn sys/sys as dba
  • 修改密码:ALTER USER user_name IDENTIFIED BY new_password;

需求:默认情况下Typecho安装完后文章链接是http://zhangguoli.cn/index.php/xxx.html这样的,强迫症是在受不了中间多了个index.php,于是想修改为:http://zhangguoli.cn/xxx.html

本文环境:
CentOS release 6.5 (Final)
Apache 2.4.29
PHP 5.6.32

Apache的安装路径: /opt/apache
网站站点文件位置: /opt/www/zhangguoli

1. 开启Apache的Rewrite模块

vi /opt/apache/conf/httpd.conf

查找httpd.conf中是否包含LoadModule rewrite_module modules/mod_rewrite.so,如果被#注释则去掉或新增。

增加配置如下:

<Directory "/opt/www/zhangguoli"> 
    Order allow,deny
    Allow from all
    AllowOverride All
</Directory>

2. 增加RewriteRule规则

- 阅读剩余部分 -

说明:本文基于CentOS release 6.5 (Final),是工作过程中记录的一些随笔,内容未做详细考究.


  • 设置DNS服务器

  vi /etc/resolv.conf
  nameserver 114.114.114.114
  • 查看Linux版本
    lsb_release -a
LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID:    CentOS
Description:    CentOS release 6.5 (Final)
Release:    6.5
Codename:    Final

通过implements ServletContextListener实现监听器Linstener

package cn.config;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

/*
* Servlet 容器启动或终止Web 应用时,会触发ServletContextEvent事件
* 
* ServletContext对象是一个为整个Web应用提供共享的内存,任何请求都可以获取里面的内容
* 实现ServletContextListener时通过ServletContext.setAttribute(key,value)将内容提交到内存中
* 其他地方通过ServletContext.getAttribute(key)获取内容(HelloWorld#doPost)
* 
* 官方对于ServletContextEvent的介绍:
* This is the event class for notifications about changes to the servlet context of a web application.
*/

public class MyLinstener implements ServletContextListener {

    /**
     * ① Servlet启动时先调用contextInitialized方法, 之后再对Filter和需要被初始化的Servlet初始化
     */
    @Override
    public void contextInitialized(ServletContextEvent paramServletContextEvent) {
        ServletContext context = paramServletContextEvent.getServletContext();
        context.setAttribute("linstener", "fromContextInitialized");
        System.out.println("...    contextInitialized    ... ");
    }

    /**
     * ② Servlet停止时先销毁所有的Servlet和Filter, 再调用contextDestroyed方法
     */
    @Override
    public void contextDestroyed(ServletContextEvent paramServletContextEvent) {
        ServletContext dest = paramServletContextEvent.getServletContext();
        System.out.println("contextDestroyed... " + dest.getAttribute("linstener"));
    }

}

web.xml配置监听器

- 阅读剩余部分 -

  1. 过滤器可以动态的拦截请求和响应, 且Filter在Servlet之前执行.
  2. 过滤器常用语编码过滤,用户是否登录,权限判断等.
  3. 通过 implements javax.servlet.Filter 实现一个过滤器

以字符编码过滤器为例

package cn.config;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CharSetFilter implements Filter {

    private String encode = "utf-8";

    /**
     * init()用于初始化工作
     * filterConfig.getInitParameter("charset")获取web.xml中配置的内容
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String defaultCharset = filterConfig.getInitParameter("charset").trim();
        this.encode = "".equals(defaultCharset) ? this.encode : defaultCharset;
        System.out.println("init complete...");
    }

    
    /**
     * doFilter()完成实际的过滤工作 FilterChain用于访问后续过滤器
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        req.setCharacterEncoding(encode);
        res.setCharacterEncoding(encode);
                System.out.println("doFilter...");
        filterChain.doFilter(request, response);
    }

    /**
     * Servlet容器在销毁过滤器实例前调用destroy()方法,释放Servlet过滤器占用的资源。
     */
    @Override
    public void destroy() {
        System.out.println("destroy complete...");
    }

}
<filter>
        <filter-name>charSetFilter</filter-name>
        <filter-class>cn.config.CharSetFilter</filter-class>
        <init-param>
            <param-name>charset</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>contentType</param-name>
            <param-value>text/html;charset=UTF-8</param-value>
        </init-param>
    </filter>
        <!-- 
         多个filter,按照filter-mapping的执行顺序执行,
         而不是按照filter的定义顺序 
         -->
    <filter-mapping>
        <filter-name>charSetFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

使用Servlet的示例代码,此处会先后输出init complete...和doFilter...

一、生命周期 init()、service()、destory()

  1. 在第一次创建Servlet的时候通过init()初始化,之后不再执行此方法
  2. 通过service()处理HTTP请求,常用doGet()、doPost()
  3. destory()在Servlet结束时执行
    最后由JVM进行垃圾回收.

二、实现方式 implements Servlet、extends GenericServlet、extends HttpServlet

HttpServlet本身就是通过implements Servlet实现的.


三、代码示例: 通过继承HttpServlet实现Servlet


- 阅读剩余部分 -

需要增加UML
需要增加UML
需要增加UML

开发中通常使用new产生一个对象的实例

无模式

//生产Audi
public class Audi{
    public Audi(){
        System.out.println("制造 audi.....");
    }
}
//生产Benz
public class Benz {
    public Benz(){
        System.out.println("制造Benz....");
    }
}
//客户使用new生产一辆车
public class Customer{
    public static void main(String[] args) {
        Audi audi = new Audi();
        Benz benz = new Benz();
    }
}

简单工厂(SimpleFactory)模式



- 阅读剩余部分 -