123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393 |
- package config
- import (
- "context"
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "strings"
- "time"
- "github.com/fsnotify/fsnotify"
- "go.etcd.io/etcd/client"
- )
- var Conf *Configure
- const ConfigPath = "conf/common.json"
- // mysql 配置
- type MysqlConfig struct {
- User string `json:"user"`
- Password string `json:"password"`
- Addr string `json:"addr"`
- DefaultDB string `json:"default_db"`
- Charset string `json:"charset"`
- MaxIdle json.Number `json:"max_idle"`
- MaxConn json.Number `json:"max_conn"`
- ServiceName string `json:"service_name"`
- ServicePort int `json:"service_port"`
- }
- // redis 配置
- type RedisConfig struct {
- Addrs string `json:"addrs"`
- Password string `json:"password"`
- DefaultDB json.Number `json:"default_db"`
- PoolSize json.Number `json:"pool_size"`
- MinIdleConns json.Number `json:"min_idle_conns"`
- MaxRetries json.Number `json:"max_retries"`
- IsCluster string `json:"is_cluster"`
- }
- type ElasticConfig struct {
- Addr string `json:"addr"`
- Sniff string `json:"sniff"`
- }
- type WarningConfig struct {
- ApiTotalCountThresholds string `json:"api_total_count_thresholds"`
- ApiDayCountThresholds string `json:"api_day_count_thresholds"`
- ApiDayThresholds string `json:"api_day_thresholds"`
- ProviderDayCountThresholds string `json:"provider_day_count_thresholds"`
- DefaultMails string `json:"default_mails"`
- MailHost string `json:"mail_host"`
- MailPassword string `json:"mail_password"`
- MailUser string `json:"mail_user"`
- ApiLogAvgElapsed string `json:"api_log_avg_elapsed"`
- ApiLogFailThreshold string `json:"api_log_fail_threshold"`
- ApiLogNorecordThreshold string `json:"api_log_norecord_threshold"`
- ProviderLogAvgElapsed string `json:"provider_log_avg_elapsed"`
- ProviderLogFailThreshold string `json:"provider_log_fail_threshold"`
- ProviderLogNorecordThreshold string `json:"provider_log_norecord_threshold"`
- LogTimeInterval string `json:"log_time_interval"`
- }
- type LogConfig struct {
- MaxSize json.Number `json:"max_size"`
- MaxBackups json.Number `json:"max_backups"`
- MaxAge json.Number `json:"max_age"`
- Level string `json:"level"`
- DisableStacktrace string `json:"disable_stacktrace"`
- }
- type RPCNode struct {
- Scheme string `json:"scheme"`
- Name string `json:"name"`
- UpdateInterval json.Number `json:"update_interval"`
- MysqlDB string `json:"mysql_db"`
- RedisDB json.Number `json:"redis_db"`
- Log LogConfig `json:"log"`
- ServiceName string `json:"service_name"`
- ServicePort json.Number `json:"service_port"`
- }
- type RPCConfig struct {
- BasePath string `json:"base_path"`
- Crontab RPCNode `json:"gd_crontab"`
- Management RPCNode `json:"gd_management"`
- Vehicle RPCNode `json:"gd_vehicle"`
- }
- type MongoConfig struct {
- User string `json:"user"`
- Password string `json:"password"`
- Addr string `json:"addr"`
- }
- type ThirdPartConfig struct {
- HttpProxyUrl string `json:"http_proxy_url" description:"数据源正向代理url"`
- EdAppId string `json:"ed_app_id"` //eds16787f343c1676853
- EdAppSecret string `json:"ed_app_secret"` //3d3f47bef850c5a2b0c15d4b94b6b3a3
- C300Token string `json:"c_300_token"` //be318b5cf56c65e9172b8636699fcf17
- ArcbangAppId string `json:"arcbang_app_id"` //476795160986910721
- ArcbangAppKey string `json:"arcbang_app_key"` //897c86f2779341e88e38b3eb9acb384f
- NjKey string `json:"nj_key"` //E78E1F76-A9FE-4687-A3EB-198B7628D959
- DbDwkey string `json:"db_dwkey"` //chejinjia
- DbToken string `json:"db_token"` //chejinjia2017030
- DbEncKey string `json:"db_enc_key"` //91724890
- ScViolationDwkey string `json:"sc_violation_dwkey"` //be2hjdeii1f90c5c55bfa0af7
- ScViolationToken string `json:"sc_violation_token"` //be2hjdeii1f90c5c55bfa0af7
- ScViolationEncKey string `json:"sc_violation_enc_key"` //33725169
- MojiAppKey string `json:"moji_app_key"` //25270402
- MojiAppSecret string `json:"moji_app_secret"` //bc1ec844f9a516919c85c09b1c75d682
- MojiAppCode string `json:"moji_app_code"` //fd4df24553a04d08a71a2566203a37db
- LcbAppCode string `json:"lcb_app_code"` //3101
- LcbSecret string `json:"lcb_secret"` //b9b548a34220f097e6c22ca933f76a8e
- JhAppKey string `json:"jh_app_key"` //1ef0aa20c3d4cbe71f4a799122625bb9
- ZxCompanyKey string `json:"zx_company_key"` //001061808271603202J1I3Q1H0T2L
- ZxCompanyCode string `json:"zx_company_code"` //65db6e13ecef31a54642df747986472a
- MsToken string `json:"ms_token"` //81ed9993bcad8cd0d1f55f9565104b76
- ZqyKey string `json:"zqy_key"` //CETRo4r-KIkk05-uoyiE-20V7NU-Ab36
- ZhUser string `json:"zh_user"` //tangmimi
- ZhPwd string `json:"zh_pwd"` //E37A41FE3B1843E1AC46E6589CD76412
- ZzxAppKey string `json:"zzx_app_key"`
- ZzxUser string `json:"zzx_user"`
- ZjtAuthorizationCode string `json:"zjt_authorization_code"` //LkPw8252672h4NmF
- ZjtCryptoKey string `json:"zjt_crypto_key"` //Wuz2162IF9O60X58
- ZjtUserNo string `json:"zjt_user_no"` //SYZNCQCAR
- DjDwkey string `json:"dj_dwkey"` //wdhyiylhotoabycqtq
- DjToken string `json:"dj_token"` //MIYYKOUKIYKKKYWH081YOIYLIOJ
- DjEncKey string `json:"dj_enc_key"` //91724890
- DjScDwkey string `json:"dj_sc_dwkey"` //whsc00081890080870
- DjScToken string `json:"dj_sc_token"` //MIYYKOUKIYKKKYWH081YOIYLIOJ
- DjScEncKey string `json:"dj_sc_enc_key"` //91724890
- DjAppid string `json:"dj_appid"` //9225417112424
- DjSecrtkey string `json:"dj_secrtkey"` //IYYTOKYLHBTLIYKYQUYLHYLIY
- DjScAppid string `json:"dj_sc_appid"` //5524892445452455145
- DjScSecrtkey string `json:"dj_sc_secrtkey"` //YUOUIYOIYKHMJHUYUIOYLIYIKYIKYIJU
- SpyUserName string `json:"spy_user_name"`
- SpyPassWord string `json:"spy_pass_word"`
- JisuAppkey string `json:"jisu_appkey"`
- BjcUserName string `json:"bjc_user_name"`
- BjcPwd string `json:"bjc_pwd"`
- BjcLoginUrl string `json:"bjc_login_url"`
- DjVinAppid string `json:"dj_vin_appid"` //9225417112424
- DjVinSecrtkey string `json:"dj_vin_secrtkey"` //IYYTOKYLHBTLIYKYQUYLHYLIY
- C003AppCode string `json:"c003_app_code"`
- WarnWebhook string `json:"warn_webhook"`
- HystrixLoopTime int `json:"hystrix_loop_time"`
-
- }
- type Configure struct {
- RunMode string `json:"run_mode"`
- AppKey string `json:"app_key"`
- AppSecret string `json:"app_secret"`
- AutoExportMail string `json:"auto_export_mail"`
- AutoExportProviderMail string `json:"auto_export_provider_mail"`
- AutoExportBusinessMail string `json:"auto_export_business_mail"`
- ReportLocalDir string `json:"report_local_dir"`
- ExceptionMail string `json:"exception_mail"`
- LogMysql MysqlConfig `json:"log_mysql"`
- Redis RedisConfig `json:"redis"`
- Elastic ElasticConfig `json:"elastic"`
- //Mongo MongoConfig `json:"mongo"`
- Rpc RPCConfig `json:"rpc"`
- Warning WarningConfig `json:warning`
- ThirdPart ThirdPartConfig `json:"third_part"`
- ZqyCountIds string `json:"zqy_count_ids"`
- BillCreateCron string `json:"bill_create_cron"`
- BillNotifyCron string `json:"bill_notify_cron"`
- WarnPeriod json.Number `json:"warn_period" description:"告警周期(分钟)"`
- WarnMinCount json.Number `json:"warn_min_count" description:"告警最小统计数"`
- WarnSendPeriod json.Number `json:"warn_send_period" 告警发送周期(多少分钟发送异常)`
- }
- func watchEtcd(keysAPI client.KeysAPI, index uint64, runmode, key string, cli client.Client) {
- basePath := fmt.Sprintf("/%s/config", runmode)
- watcherOptions := &client.WatcherOptions{
- AfterIndex: index,
- Recursive: true,
- }
- watcher := keysAPI.Watcher(basePath, watcherOptions)
- for {
- r, err := watcher.Next(context.Background())
- if err != nil || r == nil {
- break
- }
- if r.Node != nil && r.PrevNode != nil {
- if r.Node.Key == r.PrevNode.Key && (r.Node.Value != r.PrevNode.Value) {
- reloadEtcd(runmode, key, cli)
- }
- }
- if r.Node != nil && r.PrevNode == nil {
- reloadEtcd(runmode, key, cli)
- }
- }
- }
- func reloadEtcd(runmode, key string, cli client.Client) {
- keysAPI := client.NewKeysAPI(cli)
- basePath := fmt.Sprintf("/%s/config", runmode)
- if resp, err := keysAPI.Get(context.Background(), basePath, &client.GetOptions{
- Recursive: true,
- }); err == nil && resp != nil && resp.Node != nil {
- conf := &Configure{}
- value := getNodeData(key, resp.Node)
- if jsonStr, err := json.Marshal(value); err == nil {
- if err := json.Unmarshal(jsonStr, &conf); err == nil {
- *Conf = *conf
- if Conf.ReportLocalDir == "" {
- Conf.ReportLocalDir = "/mnt/"
- }
- return
- } else {
- fmt.Printf("json Unmarshal failed. error:%s", err)
- }
- } else {
- fmt.Printf("json Marshal failed. error:%s", err)
- }
- } else {
- fmt.Printf("get %s failed. error:%s", basePath, err)
- }
- }
- // key 为加密密钥
- func GetConfig(runmode, key string, cli client.Client) *Configure {
- keysAPI := client.NewKeysAPI(cli)
- basePath := fmt.Sprintf("/%s/config", runmode)
- if resp, err := keysAPI.Get(context.Background(), basePath, &client.GetOptions{
- Recursive: true,
- }); err == nil && resp != nil && resp.Node != nil {
- Conf = &Configure{}
- value := getNodeData(key, resp.Node)
- if jsonStr, err := json.Marshal(value); err == nil {
- if err := json.Unmarshal(jsonStr, &Conf); err == nil {
- go watchEtcd(keysAPI, resp.Index, runmode, key, cli)
- if Conf.ReportLocalDir == "" {
- Conf.ReportLocalDir = "/mnt/"
- }
- return Conf
- } else {
- fmt.Printf("json Unmarshal failed. error:%s", err)
- }
- } else {
- fmt.Printf("json Marshal failed. error:%s", err)
- }
- } else {
- fmt.Printf("get %s failed. error:%s", basePath, err)
- os.Exit(1)
- }
- return nil
- }
- // 递归取出node的叶子节点值
- func getNodeData(key string, head *client.Node) (value interface{}) {
- s0 := strings.Split(head.Key, "/")
- len0 := len(s0)
- if len0 == 0 {
- return
- }
- if head.Dir {
- mapData := map[string]interface{}{}
- for _, node := range head.Nodes {
- s1 := strings.Split(node.Key, "/")
- len1 := len(s1)
- if len1 == 0 {
- break
- }
- mapData[s1[len1-1]] = getNodeData(key, node)
- }
- value = mapData
- } else {
- if key != "" && head.Value != "" {
- if bytesData, err := Base64URLDecode(head.Value); err != nil {
- fmt.Printf("Base64URLDecode(%s) failed. error:%s", head.Value, err)
- os.Exit(1)
- } else {
- if data, err := AesDecrypt(bytesData, []byte(key)); err != nil {
- fmt.Printf("AesDecrypt failed. error:%s", err)
- os.Exit(1)
- } else {
- value = string(data)
- }
- }
- } else {
- // 无加密,直接取值
- value = head.Value
- }
- }
- return
- }
- // 适配k8s 方式
- // 公共配置会以configmap的方式映射到容器的conf/common.json中
- func GetConfigForK8s() *Configure {
- buffer, err := ioutil.ReadFile(ConfigPath)
- if err != nil {
- fmt.Printf("get %s failed. error:%s", ConfigPath, err)
- return nil
- }
- Conf = &Configure{}
- if err := json.Unmarshal(buffer, Conf); err != nil {
- fmt.Printf("json Unmarshal failed. error:%s", err)
- return nil
- }
- if Conf.ReportLocalDir == "" {
- Conf.ReportLocalDir = "/mnt/"
- }
- go watchConfigFileForK8s()
- return Conf
- }
- func ReloadConfigForK8s() {
- buffer, err := ioutil.ReadFile(ConfigPath)
- if err != nil {
- fmt.Printf("get %s failed. error:%s", ConfigPath, err)
- }
- confTmp := &Configure{}
- if err := json.Unmarshal(buffer, confTmp); err != nil {
- fmt.Printf("json Unmarshal failed. error:%s", err)
- }
- Conf = confTmp
- if Conf.ReportLocalDir == "" {
- Conf.ReportLocalDir = "/mnt/"
- }
- }
- // 判断路径文件/文件夹是否存在
- func Exists(path string) bool {
- _, err := os.Stat(path)
- if err != nil {
- if os.IsExist(err) {
- return true
- }
- return false
- }
- return true
- }
- func watchConfigFileForK8s() {
- fileExist := true
- watch, err := fsnotify.NewWatcher()
- if err != nil {
- fmt.Printf("new file watcher failed\n\n")
- os.Exit(1)
- }
- defer watch.Close()
- /*err = watch.Add(ConfigPath)
- if err != nil {
- fmt.Printf("add file watcher failed\n\n")
- os.Exit(1)
- }*/
- for {
- // 判断文件是否存在
- if !Exists(ConfigPath) {
- time.Sleep(10 * time.Second)
- fileExist = false
- continue
- } else {
- watch.Remove(ConfigPath)
- watch.Add(ConfigPath)
- if !fileExist { // 文件重新创建
- ReloadConfigForK8s()
- }
- fileExist = true
- }
- select {
- case ev := <-watch.Events:
- {
- fmt.Println("op : ", ev.Op)
- ReloadConfigForK8s()
- }
- case err := <-watch.Errors:
- {
- fmt.Println("error : ", err)
- continue
- }
- }
- }
- }
|