package main

import (
    "encoding/json"
    "flag"
    "fmt"
    color "github.com/fatih/color"
    "github.com/gosexy/redis"
    "strings"
    "time"
)

func GetInfo(c *redis.Client, sec string) map[string]string {
    s, err := c.Info(sec)
    if err != nil {
        fmt.Println("get key failure")
        return nil
    }
    a1 := strings.Split(s, "\r\n")
    m1 := make(map[string]string)
    for i := 1; i < len(a1); i++ {
        if !strings.Contains(a1[i], ":") {
            continue
        }
        a2 := strings.Split(a1[i], ":")
        m1[a2[0]] = a2[1]
    }
    return m1
}

func Help() {
    color.Cyan("Version: xredis_v1.0\n")
    fmt.Printf("Usage:./xredis\n")
    fmt.Printf("Usage:./xredis --i=\"192.168.1.1\" -p=\"6379\" -w=\"password\"\n")
    fmt.Printf("Usage:./xredis -j=Server args is (Server|Clients|Memory|Persistence|Stats|Replication|CPU)\n")
    fmt.Printf("Usage:./xredis -k=Server args is (Server|Clients|Memory|Persistence|Stats|Replication|CPU)\n")
    fmt.Printf("Usage:./xredis -c=false show color\n")
    fmt.Printf("defautl ip=127.0.0.1 default port=6379\n")
}

func main() {
    help := flag.Bool("h", false, "show help")
    ip := flag.String("i", "127.0.0.1", "redis server ip")
    port := flag.Uint("p", 6379, "redis server port")
    pass := flag.String("w", "", "redis server password")
    // showColor := flag.Bool("c", true, "show or not show color")
    xjson := flag.String("j", "", "Server|Clients|Memory|Persistence|Stats|Replication|CPU")
    xkey := flag.String("k", "", "Server|Clients|Memory|Persistence|Stats|Replication|CPU")
    flag.Parse()

    // if *showColor {
    //  color.Enable()
    // }

    if *help {
        Help()
        return
    }

    T_out := time.Duration(time.Second * 10) //connect redis timeout

    client := redis.New()
    err := client.ConnectWithTimeout(*ip, *port, T_out)
    if err != nil {
        fmt.Println("connect redis-server failure")
        return
    }
    //redis auth
    if *pass != "" {
        ss, _ := client.Auth(*pass)
        if ss != "OK" {
            fmt.Println(ss)
        }
    }

    if *xjson != "" {
        mm := GetInfo(client, *xjson)
        b, _ := json.Marshal(mm)
        fmt.Println(string(b))
        return
    }
    if *xkey != "" {
        mm := GetInfo(client, *xkey)
        for k, v := range mm {
            fmt.Printf("%s=%s\n", k, v)
        }
        return
    }

    m1 := GetInfo(client, "Server")
    m2 := GetInfo(client, "Clients")
    m3 := GetInfo(client, "Memory")
    //m4 := GetInfo(client, "Persistence")
    m5 := GetInfo(client, "Stats")
    m6 := GetInfo(client, "Replication")
    m7 := GetInfo(client, "CPU")
    client.Quit()
    color.Cyan("  redis_version             : %-12s", m1["redis_version"])
    color.Green("|   redis_mode                : %s\n", m1["redis_mode"])
    color.Cyan("  uptime_days               : %-12s", m1["uptime_in_days"])
    color.Green("|   config_file               : %s\n", m1["config_file"])
    color.Cyan("  connected_clients         : %-12s", m2["connected_clients"])
    color.Green("|   blocked_clients           : %s\n", m2["blocked_clients"])
    color.Cyan("  used_memory               : %-12s", m3["used_memory_human"])
    color.Green("|   used_memory_peak          : %s\n", m3["used_memory_peak_human"])
    color.Cyan("  input_bytes               : %-12s", m5["total_net_input_bytes"])
    color.Green("|   output_bytes              : %s\n", m5["total_net_output_bytes"])
    color.Cyan("  instantaneous_input_kbps  : %-12s", m5["instantaneous_input_kbps"])
    color.Green("|   instantaneous_output_kbps : %s\n", m5["instantaneous_output_kbps"])
    color.Cyan("  expired_keys              : %-12s", m5["expired_keys"])
    color.Green("|   evicted_keys              : %s\n", m5["evicted_keys"])
    color.Cyan("  role                      : %-12s", m6["role"])
    color.Green("|   connected_slaves          : %s\n", m6["connected_slaves"])
    color.Cyan("  used_cpu_sys              : %-12s", m7["used_cpu_sys"])
    color.Green("|   used_cpu_user             : %s\n", m7["used_cpu_user"])
}

package main
 
import (
    "crypto/tls"
    "fmt"
    "log"
    "net"
    "net/smtp"
)
 
func main() {
    host := "smtp.timiguo.com"
    port := 465
    email := "[email protected]"
    password := "******"
    toEmail := "[email protected]"
 
    header := make(map[string]string)
    header["From"] = "test" + "<" + email + ">"
    header["To"] = toEmail
    header["Subject"] = "邮件标题"
    header["Content-Type"] = "text/html; charset=UTF-8"
 
    body := "我是内容!"
 
    message := ""
    for k, v := range header {
        message += fmt.Sprintf("%s: %s\r\n", k, v)
    }
    message += "\r\n" + body
 
    auth := smtp.PlainAuth(
        "",
        email,
        password,
        host,
    )
 
    err := SendMailUsingTLS(
        fmt.Sprintf("%s:%d", host, port),
        auth,
        email,
        []string{toEmail},
        []byte(message),
    )
 
    if err != nil {
        panic(err)
    }
}
 
//return a smtp client
func Dial(addr string) (*smtp.Client, error) {
    conn, err := tls.Dial("tcp", addr, nil)
    if err != nil {
        log.Println("Dialing Error:", err)
        return nil, err
    }
    //分解主机端口字符串
    host, _, _ := net.SplitHostPort(addr)
    return smtp.NewClient(conn, host)
}
 
//参考net/smtp的func SendMail()
//使用net.Dial连接tls(ssl)端口时,smtp.NewClient()会卡住且不提示err
//len(to)>1时,to[1]开始提示是密送
func SendMailUsingTLS(addr string, auth smtp.Auth, from string,
    to []string, msg []byte) (err error) {
 
    //create smtp client
    c, err := Dial(addr)
    if err != nil {
        log.Println("Create smpt client error:", err)
        return err
    }
    defer c.Close()
 
    if auth != nil {
        if ok, _ := c.Extension("AUTH"); ok {
            if err = c.Auth(auth); err != nil {
                log.Println("Error during AUTH", err)
                return err
            }
        }
    }
 
    if err = c.Mail(from); err != nil {
        return err
    }
 
    for _, addr := range to {
        if err = c.Rcpt(addr); err != nil {
            return err
        }
    }
 
    w, err := c.Data()
    if err != nil {
        return err
    }
 
    _, err = w.Write(msg)
    if err != nil {
        return err
    }
 
    err = w.Close()
    if err != nil {
        return err
    }
 
    return c.Quit()
}

pm.max_requests = 1000

设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0.

这段配置的意思是,当一个 PHP-CGI 进程处理的请求数累积到 1000 个后,自动重启该进程。

但是为什么要重启进程呢?

一般在项目中,我们多多少少都会用到一些 PHP 的第三方库,这些第三方库经常存在内存泄漏问题,如果不定期重启 PHP-CGI 进程,势必造成内存使用量不断增长。因此 PHP-FPM 作为 PHP-CGI 的管理器,提供了这么一项监控功能,对请求达到指定次数的 PHP-CGI 进程进行重启,保证内存使用量不增长。

一、centos

cd /etc/sysconfig/network-scripts
cp ifcfg-eth0 ifcfg-eth0:0
    DEVICE=eth0:0   #这个要改
    IPADDR=192.168.3.247 #设置成另外一个ip

vim ifcfg-eth0:0
ifdown eth0 && ifup eth0    #不需要重启
ifconfig

二、ubuntu

sudo vi /etc/network/interfaces

直接复制一个eth0修改即可

sudo /etc/init.d/networking restart

redis中无配置启动用户信息,需要添加redis用户,后以其启动

useradd -s /bash/false -M redis

sudo -u redis /xxx/redis-server /xxx/etc/redis.conf >/dev/null 2>&1 &