首页 > 安全资讯 >

前端php加后端golang微信发红包

16-03-23

程序说明:最近公司服务号搞发红包活动,活动那个火啊(一帮见钱眼开的家伙,当然我也是^&^)但是服务器太烂(单台小企业服务器只支持php5 2),并发量和php性能都不够,结果导致很多红包没发出去,被领导那个P


程序说明:最近公司服务号搞发红包活动,活动那个火啊(一帮见钱眼开的家伙,当然我也是^&^)但是服务器太烂(单台小企业服务器只支持php5.2),并发量和php性能都不够,结果导致很多红包没发出去,被领导那个P啊,(一个SX领导),于是就想前端用php把用户的openid和红包的存到redis里,然后后端用golang在服务器里并行发,事实证明too young too simple,由于golang协程是并行的(几乎同一时间),所以导致订单号都是一样的,没办法暂时还没想到解决方案(有解决方案的兄弟可以私信我),只能折中,每隔三秒自动一个个的发,经过两天的奋战终于大功告成!


注意:请go build后再运行,速度跟go run差?倍,反正速差非常多,代码阅读对像,有Golang基础的兄弟


package main

import (
    "bytes"
    "crypto/md5"
    "crypto/tls"
    "crypto/x509"
    "encoding/hex"
    "encoding/xml"
    "fmt"
    "github.com/garyburd/redigo/redis"
    "io/ioutil"
    "log"
    "math/rand"
    "net/http"
    "os"
    "runtime"
    "strconv"
    "strings"
    "time"
)

type Bonus struct {
    XMLName      xml.Name `xml:"xml"`
    Act_name     string   `xml:"act_name"`
    Client_ip    string   `xml:"client_ip"`
    Mch_billno   string   `xml:"mch_billno"`
    Mch_id       string   `xml:"mch_id"`
    Nonce_str    string   `xml:"nonce_str"`
    Re_openid    string   `xml:"re_openid"`
    Remark       string   `xml:"remark"`
    Send_name    string   `xml:"send_name"`
    Total_amount int      `xml:"total_amount"`
    Total_num    int      `xml:"total_num"`
    Wishing      string   `xml:"wishing"`
    Wxappid      string   `xml:"wxappid"`
    Sign         string   `xml:"sign"`
}

const (
    WECHATCERTPATH    = "D:/apiclient_cert.pem"            //客户端证书存放绝对路径
    WECHATKEYPATH     = "D:/apiclient_key.pem"             //客户端私匙存放绝对路径
    WECHATCAPATH      = "D:/wwwroot/rootca.pem"                    //服务端证书存放绝对路径
    WECHATURL         = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack" //微信红包发送链接
    REDISURL          = "127.0.0.1:6379"                                              //redis地址
    ENDTIME           = "201603221657"                                                //红包活动结束时间
    OPENIDS           = "openids"                                                     //中奖用户redis openid列表名
    BONUSPRICEPOSTFIX = "_bonusprice"                                                 //redis get对应用户红包价格的后缀 例:set openid+BONUSPRICEPOSTFIX price

    //微信红包内容XML设置
    ACT_NAME  = ""          //活动名
    CLIENT_IP = "" //服务器IP
    MCH_ID    = "1231911402"    //商户号
    REMARK    = ""
    SEND_NAME = ""
    TOTAL_NUM = 1 //红包个数
    WISHING   = ""
    WXAPPID   = ""
    KEY       = ""
)

var _tlsConfig *tls.Config

func getTLSConfig() (*tls.Config, error) {
    if _tlsConfig != nil {
        return _tlsConfig, nil
    }

    // load cert
    cert, err := tls.LoadX509KeyPair(WECHATCERTPATH, WECHATKEYPATH)
    if err != nil {
        fmt.Println("load wechat keys fail", err)
        return nil, err
    }

    // load root ca
    caData, err := ioutil.ReadFile(WECHATCAPATH)
    if err != nil {
        fmt.Println("read wechat ca fail", err)
        return nil, err
    }
    pool := x509.NewCertPool()
    pool.AppendCertsFromPEM(caData)

    _tlsConfig = &tls.Config{
        Certificates: []tls.Certificate{cert},
        RootCAs:      pool,
    }
    return _tlsConfig, nil
}

func SecurePost(url string, xmlContent []byte) (*http.Response, error) {
    tlsConfig, err := getTLSConfig()
    if err != nil {
        return nil, err
    }

    tr := &http.Transport{TLSClientConfig: tlsConfig}
    client := &http.Client{Transport: tr}

    return client.Post(
        url,
        "text/xml",
        bytes.NewBuffer(xmlContent))
}

func bonus(oid string, price int) {

    openid := oid               //openid
    total_amount := price * 100 //金额

    //生成随机数并md5加密随机数
    rand.Seed(time.Now().UnixNano())
    md5Ctx1 := md5.New()
    md5Ctx1.Write([]byte(strconv.Itoa(rand.Intn(1000))))
    nonce_str := hex.EncodeToString(md5Ctx1.Sum(nil)) //随机数
    //订单号
    mch_billno := MCH_ID + time.Now().Format("20060102") + strconv.FormatInt(time.Now().Unix(), 10)
    // 生成签名
    s1 := "act_name=" + ACT_NAME + "&client_ip=" + CLIENT_IP + "&mch_billno=" + mch_billno + "&mch_id=" + MCH_ID + "&nonce_str=" + nonce_str + "&re_openid=" + openid + "&remark=" + REMARK + "&send_name=" + SEND_NAME + "&total_amount=" + strconv.Itoa(total_amount) + "&total_num=" + strconv.Itoa(TOTAL_NUM) + "&wishing=" + WISHING + "&wxappid=" + WXAPPID + "&key=" + KEY

    md5Ctx2 := md5.New()
    md5Ctx2.Write([]byte(s1))
    s1 = hex.EncodeToString(md5Ctx2.Sum(nil))
    sign := strings.ToUpper(s1) //签名

    v := &Bonus{
        Act_name:     ACT_NAME,
        Client_ip:    CLIENT_IP,
        Mch_billno:   mch_billno,
        Mch_id:       MCH_ID,
        Nonce_str:    nonce_str,
        Remark:       REMARK,
        Send_name:    SEND_NAME,
        Re_openid:    openid,
        Total_amount: total_amount,
        Total_num:    TOTAL_NUM,
        Wishing:      WISHING,
        Wxappid:      WXAPPID,
        Sign:         sign}

    output, err := xml.MarshalIndent(v, "  ", "    ")
    if err != nil {
        fmt.Printf("error: %v\n", err)
    }
    // os.Stdout.Write(output)
    //POST数据
    SecurePost(WECHATURL, output)

}

func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())

    ticker := time.NewTicker(3 * time.Second)

    for {
        if time.Now().Format("200601021504") >= ENDTIME {
            log.Printf("over")
            break
            ticker.Stop()
            os.Exit(1)
        } else {
            <-ticker.C
            //redis
            redisDataBase, _ := redis.Dial("tcp", REDISURL)
            openidsLen, _ := redis.Int(redisDataBase.Do("llen", OPENIDS))
            if openidsLen > 0 {
                log.Printf("Start Bonus")
                openid, _ := redis.String(redisDataBase.Do("lpop", OPENIDS))
                log.Printf(openid)
                //获取红包价格
                bonusPrice, _ := redis.Int(redisDataBase.Do("get", openid+BONUSPRICEPOSTFIX))
                redisDataBase.Do("del", openid+BONUSPRICEPOSTFIX)
                redisDataBase.Close()
                bonus(openid, bonusPrice)
                log.Printf("End Bonus")
            } else {
                log.Printf("Openids Is Empty")
                redisDataBase.Close()
            }
        }

    }

}

 

相关文章
最新文章
热点推荐