Skip to content
Snippets Groups Projects
Commit 49a2ca31 authored by AlexStocks's avatar AlexStocks
Browse files

Init

parent 9f1f59ee
No related branches found
No related tags found
No related merge requests found
Showing
with 1500 additions and 217 deletions
This diff is collapsed.
# dubbo-go #
Alibaba Dubbo golang version.
## feature ##
---
- 1 Transport: HTTP(√)
- 2 Codec: JsonRPC(√), Hessian(X)
- 3 SOA:Service Register(√), Service Watch(√), Service Notify(√)
Apache Dubbo golang version.
- 4 Registry: ZooKeeper(√), Etcd(X), Redis(X)
- 5 Strategy: Failover(√), Failfast(√)
- 6 Load Balance: Random(√), RoundRobin(√)
- 7 Role: Consumer(√), Provider(X)
## license
Apache License, Version 2.0
## Feature list ##
---
+ 1 Transport: HTTP(√)
+ 2 Codec: JsonRPC(√), Hessian(X)
+ 3 Service discovery:Service Register(√), Service Watch(√)
+ 4 Registry: ZooKeeper(√), Etcd(X), Redis(X)
+ 5 Strategy: Failover(√), Failfast(√)
+ 6 Load Balance: Random(√), RoundRobin(√)
+ 7 Role: Consumer(√), Provider(X)
package client
import (
"bufio"
"bytes"
"context"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
"strconv"
"strings"
"sync/atomic"
"time"
)
import (
jerrors "github.com/juju/errors"
)
import (
"github.com/dubbo/dubbo-go/registry"
)
const (
DUBBOGO_CTX_KEY = "dubbogo-ctx"
)
//////////////////////////////////////////////
// Request
//////////////////////////////////////////////
type Request struct {
ID int64
group string
protocol string
version string
service string
method string
args interface{}
contentType string
}
func (r *Request) ServiceConfig() registry.ServiceConfigIf {
return &registry.ServiceConfig{
Protocol: r.protocol,
Service: r.service,
Group: r.group,
Version: r.version,
}
}
//////////////////////////////////////////////
// HTTP Client
//////////////////////////////////////////////
type HTTPOptions struct {
HandshakeTimeout time.Duration
HTTPTimeout time.Duration
}
var defaultHTTPOptions = HTTPOptions{
HandshakeTimeout: 3e9,
HTTPTimeout: 3e9,
}
type HTTPClient struct {
ID int64
options HTTPOptions
}
func NewHTTPClient(opt *HTTPOptions) *HTTPClient {
if opt == nil {
opt = &defaultHTTPOptions
}
switch {
case opt.HandshakeTimeout == 0:
opt.HandshakeTimeout = defaultHTTPOptions.HandshakeTimeout
case opt.HTTPTimeout == 0:
opt.HTTPTimeout = defaultHTTPOptions.HTTPTimeout
}
t := time.Now()
return &HTTPClient{
ID: int64(uint32(t.Second() * t.Nanosecond())),
options: *opt,
}
}
func (c *HTTPClient) NewRequest(conf registry.ServiceConfig, method string, args interface{}) Request {
return Request{
ID: atomic.AddInt64(&c.ID, 1),
group: conf.Group,
protocol: conf.Protocol,
version: conf.Version,
service: conf.Service,
method: method,
args: args,
}
}
func (c *HTTPClient) Call(ctx context.Context, service registry.ServiceURL, req Request, rsp interface{}) error {
// header
httpHeader := http.Header{}
httpHeader.Set("Content-Type", "application/json")
httpHeader.Set("Accept", "application/json")
reqTimeout := c.options.HTTPTimeout
if len(service.Query.Get("timeout")) != 0 {
if timeout, err := strconv.Atoi(service.Query.Get("timeout")); err == nil {
timeoutDuration := time.Duration(timeout) * time.Millisecond
if timeoutDuration < reqTimeout {
reqTimeout = timeoutDuration
}
}
}
if reqTimeout <= 0 {
reqTimeout = 1e8
}
httpHeader.Set("Timeout", fmt.Sprintf("%d", reqTimeout))
if md, ok := ctx.Value(DUBBOGO_CTX_KEY).(map[string]string); ok {
for k := range md {
httpHeader.Set(k, md[k])
}
}
// body
codec := newJsonClientCodec()
codecData := CodecData{
ID: req.ID,
Method: req.method,
Args: req.args,
}
reqBody, err := codec.Write(&codecData)
if err != nil {
return jerrors.Trace(err)
}
rspBody, err := c.Do(service.Location, service.Path, httpHeader, reqBody)
if err != nil {
return jerrors.Trace(err)
}
return jerrors.Trace(codec.Read(rspBody, rsp))
}
// !!The high level of complexity and the likelihood that the fasthttp client has not been extensively used
// in production means that you would need to expect a very large benefit to justify the adoption of fasthttp today.
// from: http://big-elephants.com/2016-12/fasthttp-client/
func (c *HTTPClient) Do(addr, path string, httpHeader http.Header, body []byte) ([]byte, error) {
u := url.URL{Host: strings.TrimSuffix(addr, ":"), Path: path}
httpReq, err := http.NewRequest("POST", u.String(), bytes.NewBuffer(body))
if err != nil {
return nil, jerrors.Trace(err)
}
httpReq.Header = httpHeader
httpReq.Close = true
reqBuf := bytes.NewBuffer(make([]byte, 0))
if err := httpReq.Write(reqBuf); err != nil {
return nil, jerrors.Trace(err)
}
tcpConn, err := net.DialTimeout("tcp", addr, c.options.HandshakeTimeout)
if err != nil {
return nil, jerrors.Trace(err)
}
defer tcpConn.Close()
setNetConnTimeout := func(conn net.Conn, timeout time.Duration) {
t := time.Time{}
if timeout > time.Duration(0) {
t = time.Now().Add(timeout)
}
conn.SetReadDeadline(t)
}
setNetConnTimeout(tcpConn, c.options.HTTPTimeout)
// defer setNetConnTimeout(tcpConn, 0)
if _, err := reqBuf.WriteTo(tcpConn); err != nil {
return nil, jerrors.Trace(err)
}
httpRsp, err := http.ReadResponse(bufio.NewReader(tcpConn), httpReq)
if err != nil {
return nil, jerrors.Trace(err)
}
defer httpRsp.Body.Close()
b, err := ioutil.ReadAll(httpRsp.Body)
if err != nil {
return nil, jerrors.Trace(err)
}
if httpRsp.StatusCode != http.StatusOK {
return nil, jerrors.New(fmt.Sprintf("http status:%q, error string:%q", httpRsp.Status, string(b)))
}
return b, nil
}
// Copyright (c) 2016 ~ 2018, Alex Stocks.
// Copyright (c) 2015 Alex Efros.
//
// The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package client
import (
"bytes"
"encoding/json"
"fmt"
"io"
"reflect"
)
import (
jerrors "github.com/juju/errors"
)
const (
MAX_JSONRPC_ID = 0x7FFFFFFF
VERSION = "2.0"
)
//////////////////////////////////////////
// codec type
//////////////////////////////////////////
type CodecType int
const (
CODECTYPE_UNKNOWN CodecType = iota
CODECTYPE_JSONRPC
)
var codecTypeStrings = [...]string{
"unknown",
"jsonrpc",
}
func (c CodecType) String() string {
typ := CODECTYPE_UNKNOWN
switch c {
case CODECTYPE_JSONRPC:
typ = c
}
return codecTypeStrings[typ]
}
func GetCodecType(t string) CodecType {
var typ = CODECTYPE_UNKNOWN
switch t {
case codecTypeStrings[CODECTYPE_JSONRPC]:
typ = CODECTYPE_JSONRPC
}
return typ
}
//////////////////////////////////////////
// json codec
//////////////////////////////////////////
type CodecData struct {
ID int64
Method string
Args interface{}
Error string
}
// response Error
type Error struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
func (e *Error) Error() string {
buf, err := json.Marshal(e)
if err != nil {
msg, err := json.Marshal(err.Error())
if err != nil {
msg = []byte("jsonrpc2.Error: json.Marshal failed")
}
return fmt.Sprintf(`{"code":%d,"message":%s}`, -32001, string(msg))
}
return string(buf)
}
type clientRequest struct {
Version string `json:"jsonrpc"`
Method string `json:"method"`
Params interface{} `json:"params"`
ID int64 `json:"id"`
}
type clientResponse struct {
Version string `json:"jsonrpc"`
ID int64 `json:"id"`
Result *json.RawMessage `json:"result,omitempty"`
Error *Error `json:"error,omitempty"`
}
func (r *clientResponse) reset() {
r.Version = ""
r.ID = 0
r.Result = nil
}
type jsonClientCodec struct {
// temporary work space
req clientRequest
rsp clientResponse
pending map[int64]string
}
func newJsonClientCodec() *jsonClientCodec {
return &jsonClientCodec{
pending: make(map[int64]string),
}
}
func (c *jsonClientCodec) Write(d *CodecData) ([]byte, error) {
// If return error: it will be returned as is for this call.
// Allow param to be only Array, Slice, Map or Struct.
// When param is nil or uninitialized Map or Slice - omit "params".
param := d.Args
if param != nil {
switch k := reflect.TypeOf(param).Kind(); k {
case reflect.Map:
if reflect.TypeOf(param).Key().Kind() == reflect.String {
if reflect.ValueOf(param).IsNil() {
param = nil
}
}
case reflect.Slice:
if reflect.ValueOf(param).IsNil() {
param = nil
}
case reflect.Array, reflect.Struct:
case reflect.Ptr:
switch k := reflect.TypeOf(param).Elem().Kind(); k {
case reflect.Map:
if reflect.TypeOf(param).Elem().Key().Kind() == reflect.String {
if reflect.ValueOf(param).Elem().IsNil() {
param = nil
}
}
case reflect.Slice:
if reflect.ValueOf(param).Elem().IsNil() {
param = nil
}
case reflect.Array, reflect.Struct:
default:
return nil, jerrors.New("unsupported param type: Ptr to " + k.String())
}
default:
return nil, jerrors.New("unsupported param type: " + k.String())
}
}
c.req.Version = "2.0"
c.req.Method = d.Method
c.req.Params = param
c.req.ID = d.ID & MAX_JSONRPC_ID
// can not use d.ID. otherwise you will get error: can not find method of rsponse id 280698512
c.pending[c.req.ID] = d.Method
buf := bytes.NewBuffer(nil)
defer buf.Reset()
enc := json.NewEncoder(buf)
if err := enc.Encode(&c.req); err != nil {
return nil, jerrors.Trace(err)
}
return buf.Bytes(), nil
}
func (c *jsonClientCodec) Read(streamBytes []byte, x interface{}) error {
c.rsp.reset()
buf := bytes.NewBuffer(streamBytes)
defer buf.Reset()
dec := json.NewDecoder(buf)
if err := dec.Decode(&c.rsp); err != nil {
if err != io.EOF {
err = jerrors.Trace(err)
}
return err
}
_, ok := c.pending[c.rsp.ID]
if !ok {
err := jerrors.Errorf("can not find method of rsponse id %v, rsponse error:%v", c.rsp.ID, c.rsp.Error)
return err
}
delete(c.pending, c.rsp.ID)
// c.rsp.ID
if c.rsp.Error != nil {
return jerrors.New(c.rsp.Error.Error())
}
return jerrors.Trace(json.Unmarshal(*c.rsp.Result, x))
}
package main
import (
"fmt"
"net/http"
_ "net/http/pprof"
"os"
"os/signal"
"strconv"
"syscall"
"time"
)
import (
"github.com/AlexStocks/goext/log"
"github.com/AlexStocks/goext/net"
log "github.com/AlexStocks/log4go"
jerrors "github.com/juju/errors"
)
import (
"github.com/dubbo/dubbo-go/client"
"github.com/dubbo/dubbo-go/registry"
)
var (
survivalTimeout int = 10e9
clientRegistry *registry.ZkConsumerRegistry
)
func main() {
var (
err error
)
err = initClientConfig()
if err != nil {
log.Error("initClientConfig() = error{%#v}", err)
return
}
initProfiling()
initClient()
time.Sleep(3e9)
gxlog.CInfo("\n\n\nstart to test jsonrpc")
for i := 0; i < 100; i++ {
testJsonrpc("A003")
time.Sleep(1e9)
}
initSignal()
}
func initClient() {
var (
err error
codecType client.CodecType
)
if clientConfig == nil {
panic(fmt.Sprintf("clientConfig is nil"))
return
}
// registry
clientRegistry, err = registry.NewZkConsumerRegistry(
registry.ApplicationConf(clientConfig.Application_Config),
registry.RegistryConf(clientConfig.Registry_Config),
registry.BalanceMode(registry.SM_RoundRobin),
registry.ServiceTTL(300e9),
)
if err != nil {
panic(fmt.Sprintf("fail to init registry.Registy, err:%s", jerrors.ErrorStack(err)))
return
}
for _, service := range clientConfig.Service_List {
err = clientRegistry.Register(service)
if err != nil {
panic(fmt.Sprintf("registry.Register(service{%#v}) = error{%v}", service, jerrors.ErrorStack(err)))
return
}
}
// consumer
clientConfig.requestTimeout, err = time.ParseDuration(clientConfig.Request_Timeout)
if err != nil {
panic(fmt.Sprintf("time.ParseDuration(Request_Timeout{%#v}) = error{%v}",
clientConfig.Request_Timeout, err))
return
}
clientConfig.connectTimeout, err = time.ParseDuration(clientConfig.Connect_Timeout)
if err != nil {
panic(fmt.Sprintf("time.ParseDuration(Connect_Timeout{%#v}) = error{%v}",
clientConfig.Connect_Timeout, err))
return
}
for idx := range clientConfig.Service_List {
codecType = client.GetCodecType(clientConfig.Service_List[idx].Protocol)
if codecType == client.CODECTYPE_UNKNOWN {
panic(fmt.Sprintf("unknown protocol %s", clientConfig.Service_List[idx].Protocol))
}
}
}
func uninitClient() {
log.Close()
}
func initProfiling() {
if !clientConfig.Pprof_Enabled {
return
}
const (
PprofPath = "/debug/pprof/"
)
var (
err error
ip string
addr string
)
ip, err = gxnet.GetLocalIP()
if err != nil {
panic("cat not get local ip!")
}
addr = ip + ":" + strconv.Itoa(clientConfig.Pprof_Port)
log.Info("App Profiling startup on address{%v}", addr+PprofPath)
go func() {
log.Info(http.ListenAndServe(addr, nil))
}()
}
func initSignal() {
signals := make(chan os.Signal, 1)
// It is not possible to block SIGKILL or syscall.SIGSTOP
signal.Notify(signals, os.Interrupt, os.Kill, syscall.SIGHUP,
syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT)
for {
sig := <-signals
log.Info("get signal %s", sig.String())
switch sig {
case syscall.SIGHUP:
// reload()
default:
go time.AfterFunc(time.Duration(survivalTimeout)*time.Second, func() {
log.Warn("app exit now by force...")
os.Exit(1)
})
// 要么survialTimeout时间内执行完毕下面的逻辑然后程序退出,要么执行上面的超时函数程序强行退出
uninitClient()
fmt.Println("app exit now...")
return
}
}
}
package main
import (
"fmt"
"os"
"path"
"time"
)
import (
"github.com/AlexStocks/goext/log"
log "github.com/AlexStocks/log4go"
config "github.com/koding/multiconfig"
)
import (
"github.com/dubbo/dubbo-go/registry"
)
const (
APP_CONF_FILE = "APP_CONF_FILE"
APP_LOG_CONF_FILE = "APP_LOG_CONF_FILE"
)
var (
clientConfig *ClientConfig
)
type (
// Client holds supported types by the multiconfig package
ClientConfig struct {
// pprof
Pprof_Enabled bool `default:"false"`
Pprof_Port int `default:"10086"`
// client
Connect_Timeout string `default:"100ms"`
connectTimeout time.Duration
Request_Timeout string `default:"5s"` // 500ms, 1m
requestTimeout time.Duration
// codec & selector & transport & registry
Selector string `default:"cache"`
Selector_TTL string `default:"10m"`
Registry string `default:"zookeeper"`
// application
Application_Config registry.ApplicationConfig
Registry_Config registry.RegistryConfig
// 一个客户端只允许使用一个service的其中一个group和其中一个version
Service_List []registry.ServiceConfig
}
)
func initClientConfig() error {
var (
confFile string
)
// configure
confFile = os.Getenv(APP_CONF_FILE)
if confFile == "" {
panic(fmt.Sprintf("application configure file name is nil"))
return nil // I know it is of no usage. Just Err Protection.
}
if path.Ext(confFile) != ".toml" {
panic(fmt.Sprintf("application configure file name{%v} suffix must be .toml", confFile))
return nil
}
clientConfig = new(ClientConfig)
config.MustLoadWithPath(confFile, clientConfig)
gxlog.CInfo("config{%#v}\n", clientConfig)
// log
confFile = os.Getenv(APP_LOG_CONF_FILE)
if confFile == "" {
panic(fmt.Sprintf("log configure file name is nil"))
return nil
}
if path.Ext(confFile) != ".xml" {
panic(fmt.Sprintf("log configure file name{%v} suffix must be .xml", confFile))
return nil
}
log.LoadConfiguration(confFile)
return nil
}
package main
import (
"context"
"fmt"
_ "net/http/pprof"
)
import (
// "github.com/AlexStocks/goext/log"
log "github.com/AlexStocks/log4go"
jerrors "github.com/juju/errors"
)
import (
"github.com/dubbo/dubbo-go/client"
"github.com/dubbo/dubbo-go/registry"
)
func testJsonrpc(userKey string) {
var (
err error
service string
method string
serviceIdx int
user *JsonRPCUser
ctx context.Context
conf registry.ServiceConfig
req client.Request
serviceURL *registry.ServiceURL
clt *client.HTTPClient
)
clt = client.NewHTTPClient(
&client.HTTPOptions{
HandshakeTimeout: clientConfig.connectTimeout,
HTTPTimeout: clientConfig.requestTimeout,
},
)
serviceIdx = -1
service = "com.ikurento.user.UserProvider"
for i := range clientConfig.Service_List {
if clientConfig.Service_List[i].Service == service && clientConfig.Service_List[i].Protocol == client.CODECTYPE_JSONRPC.String() {
serviceIdx = i
break
}
}
if serviceIdx == -1 {
panic(fmt.Sprintf("can not find service in config service list:%#v", clientConfig.Service_List))
}
// Create request
method = string("GetUser")
// gxlog.CInfo("jsonrpc selected service %#v", clientConfig.Service_List[serviceIdx])
conf = registry.ServiceConfig{
Group: clientConfig.Service_List[serviceIdx].Group,
Protocol: client.CodecType(client.CODECTYPE_JSONRPC).String(),
Version: clientConfig.Service_List[serviceIdx].Version,
Service: clientConfig.Service_List[serviceIdx].Service,
}
// Attention the last parameter : []UserKey{userKey}
req = clt.NewRequest(conf, method, []string{userKey})
serviceURL, err = clientRegistry.Filter(req.ServiceConfig(), 1)
if err != nil {
log.Error("registry.Filter(conf:%#v) = error:%s", req.ServiceConfig(), jerrors.ErrorStack(err))
// gxlog.CError("registry.Filter(conf:%#v) = error:%s", req.ServiceConfig(), jerrors.ErrorStack(err))
return
}
log.Debug("got serviceURL: %s", serviceURL)
// Set arbitrary headers in context
ctx = context.WithValue(context.Background(), client.DUBBOGO_CTX_KEY, map[string]string{
"X-Proxy-Id": "dubbogo",
"X-Services": service,
"X-Method": method,
})
user = new(JsonRPCUser)
// Call service
if err = clt.Call(ctx, *serviceURL, req, user); err != nil {
log.Error("client.Call() return error:%+v", jerrors.ErrorStack(err))
// gxlog.CError("client.Call() return error:%+v", jerrors.ErrorStack(err))
return
}
log.Info("response result:%s", user)
// gxlog.CInfo("response result:%s", user)
}
package main
import (
"fmt"
)
import (
"github.com/AlexStocks/goext/time"
)
type JsonRPCUser struct {
ID string `json:"id"`
Name string `json:"name"`
Age int64 `json:"age"`
Time int64 `json:"time"`
Sex string `json:"sex"`
}
func (u JsonRPCUser) String() string {
return fmt.Sprintf(
"User{ID:%s, Name:%s, Age:%d, Time:%s, Sex:%s}",
u.ID, u.Name, u.Age, gxtime.YMDPrint(int(u.Time), 0), u.Sex,
)
}
package main
var (
Version = "0.3.1"
)
#!/usr/bin/env bash
# ******************************************************
# DESC : dubbogo app devops script
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-05-13 02:01
# FILE : load.sh
# ******************************************************
APP_NAME="APPLICATION_NAME"
APP_ARGS=""
SLEEP_INTERVAL=5
MAX_LIFETIME=4000
PROJECT_HOME=""
OS_NAME=`uname`
if [[ ${OS_NAME} != "Windows" ]]; then
PROJECT_HOME=`pwd`
PROJECT_HOME=${PROJECT_HOME}"/"
else
APP_NAME="APPLICATION_NAME.exe"
fi
export APP_CONF_FILE=${PROJECT_HOME}"TARGET_CONF_FILE"
export APP_LOG_CONF_FILE=${PROJECT_HOME}"TARGET_LOG_CONF_FILE"
# export GOTRACEBACK=system
# export GODEBUG=gctrace=1
usage() {
echo "Usage: $0 start"
echo " $0 stop"
echo " $0 term"
echo " $0 restart"
echo " $0 list"
echo " $0 monitor"
echo " $0 crontab"
exit
}
start() {
APP_LOG_PATH=${PROJECT_HOME}"logs/"
mkdir -p ${APP_LOG_PATH}
APP_BIN=${PROJECT_HOME}sbin/${APP_NAME}
chmod u+x ${APP_BIN}
# CMD="nohup ${APP_BIN} ${APP_ARGS} >>${APP_NAME}.nohup.out 2>&1 &"
CMD="${APP_BIN}"
eval ${CMD}
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
fi
CUR=`date +%FT%T`
if [ "${PID}" != "" ]; then
for p in ${PID}
do
echo "start ${APP_NAME} ( pid =" ${p} ") at " ${CUR}
done
fi
}
stop() {
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
fi
if [ "${PID}" != "" ];
then
for ps in ${PID}
do
echo "kill -SIGINT ${APP_NAME} ( pid =" ${ps} ")"
kill -2 ${ps}
done
fi
}
term() {
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
fi
if [ "${PID}" != "" ];
then
for ps in ${PID}
do
echo "kill -9 ${APP_NAME} ( pid =" ${ps} ")"
kill -9 ${ps}
done
fi
}
list() {
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s\n", $1, $2, $9, $10)}'`
if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{printf("%s,%s,%s,%s,%s\n", $1, $4, $6, $7, $8)}'`
fi
if [ "${PID}" != "" ]; then
echo "list ${APP_NAME}"
if [[ ${OS_NAME} == "Linux" || ${OS_NAME} == "Darwin" ]]; then
echo "index: user, pid, start, duration"
else
echo "index: PID, WINPID, UID, STIME, COMMAND"
fi
idx=0
for ps in ${PID}
do
echo "${idx}: ${ps}"
((idx ++))
done
fi
}
monitor() {
idx=0
while true; do
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
fi
if [[ "${PID}" == "" ]]; then
start
idx=0
fi
((LIFE=idx*${SLEEP_INTERVAL}))
echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
((idx ++))
sleep ${SLEEP_INTERVAL}
done
}
crontab() {
idx=0
while true; do
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $2}'`
if [[ ${OS_NAME} != "Linux" && ${OS_NAME} != "Darwin" ]]; then
PID=`ps aux | grep -w ${APP_NAME} | grep -v grep | awk '{print $1}'`
fi
if [[ "${PID}" == "" ]]; then
start
idx=0
fi
((LIFE=idx*${SLEEP_INTERVAL}))
echo "${APP_NAME} ( pid = " ${PID} ") has been working in normal state for " $LIFE " seconds."
((idx ++))
sleep ${SLEEP_INTERVAL}
if [[ ${LIFE} -gt ${MAX_LIFETIME} ]]; then
kill -9 ${PID}
fi
done
}
opt=$1
case C"$opt" in
Cstart)
start
;;
Cstop)
stop
;;
Cterm)
term
;;
Crestart)
term
start
;;
Clist)
list
;;
Cmonitor)
monitor
;;
Ccrontab)
crontab
;;
C*)
usage
;;
esac
# dubbogo application configure script
# ******************************************************
# DESC : dubbogo environment variable
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-07-12 16:29
# FILE : app.properties
# ******************************************************
export TARGET_EXEC_NAME="user_info_client"
# BUILD_PACKAGE="dubbogo-examples/user-info/client/app"
export BUILD_PACKAGE="app"
export TARGET_CONF_FILE="conf/client.toml"
export TARGET_LOG_CONF_FILE="conf/log.xml"
#!/usr/bin/env bash
# ******************************************************
# DESC : build script
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-07-12 16:28
# FILE : build.sh
# ******************************************************
rm -rf target/
PROJECT_HOME=`pwd`
TARGET_FOLDER=${PROJECT_HOME}/target/${GOOS}
TARGET_SBIN_NAME=${TARGET_EXEC_NAME}
version=`cat app/version.go | grep Version | awk -F '=' '{print $2}' | awk -F '"' '{print $2}'`
if [[ ${GOOS} == "windows" ]]; then
TARGET_SBIN_NAME=${TARGET_SBIN_NAME}.exe
fi
TARGET_NAME=${TARGET_FOLDER}/${TARGET_SBIN_NAME}
if [[ $PROFILE == "dev" || $PROFILE == "test" ]]; then
# GFLAGS=-gcflags "-N -l" -race -x -v # -x会把go build的详细过程输出
# GFLAGS=-gcflags "-N -l" -race -v
# GFLAGS="-gcflags \"-N -l\" -v"
cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -gcflags "-N -l" -x -v -i -o ${TARGET_NAME} && cd -
else
# -s去掉符号表(然后panic时候的stack trace就没有任何文件名/行号信息了,这个等价于普通C/C++程序被strip的效果),
# -w去掉DWARF调试信息,得到的程序就不能用gdb调试了。-s和-w也可以分开使用,一般来说如果不打算用gdb调试,
# -w基本没啥损失。-s的损失就有点大了。
cd ${BUILD_PACKAGE} && GOOS=$GOOS GOARCH=$GOARCH go build -ldflags "-w" -x -v -i -o ${TARGET_NAME} && cd -
fi
TAR_NAME=${TARGET_EXEC_NAME}-${version}-`date "+%Y%m%d-%H%M"`-${PROFILE}
mkdir -p ${TARGET_FOLDER}/${TAR_NAME}
SBIN_DIR=${TARGET_FOLDER}/${TAR_NAME}/sbin
BIN_DIR=${TARGET_FOLDER}/${TAR_NAME}
CONF_DIR=${TARGET_FOLDER}/${TAR_NAME}/conf
mkdir -p ${SBIN_DIR}
mkdir -p ${CONF_DIR}
mv ${TARGET_NAME} ${SBIN_DIR}
cp -r assembly/bin ${BIN_DIR}
cd ${BIN_DIR}/bin/ && mv load.sh load_${TARGET_EXEC_NAME}.sh && cd -
platform=$(uname)
# modify APPLICATION_NAME
if [ ${platform} == "Darwin" ]; then
sed -i "" "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
else
sed -i "s~APPLICATION_NAME~${TARGET_EXEC_NAME}~g" ${BIN_DIR}/bin/*
fi
# modify TARGET_CONF_FILE
if [ ${platform} == "Darwin" ]; then
sed -i "" "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
else
sed -i "s~TARGET_CONF_FILE~${TARGET_CONF_FILE}~g" ${BIN_DIR}/bin/*
fi
# modify TARGET_LOG_CONF_FILE
if [ ${platform} == "Darwin" ]; then
sed -i "" "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
else
sed -i "s~TARGET_LOG_CONF_FILE~${TARGET_LOG_CONF_FILE}~g" ${BIN_DIR}/bin/*
fi
cp -r profiles/${PROFILE}/* ${CONF_DIR}
cd ${TARGET_FOLDER}
tar czf ${TAR_NAME}.tar.gz ${TAR_NAME}/*
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for dev env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2017-10-18 13:24
# FILE : dev.sh
# ******************************************************
set -e
export GOOS=linux
export GOARCH=amd64
export PROFILE="dev"
PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for release env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-07-12 16:34
# FILE : test.sh
# ******************************************************
set -e
export GOOS=linux
export GOARCH=amd64
export PROFILE="release"
export PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for test env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-07-12 16:34
# FILE : test.sh
# ******************************************************
set -e
export GOOS=linux
export GOARCH=amd64
export PROFILE="test"
export PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for dev env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2017-10-18 13:24
# FILE : dev.sh
# ******************************************************
set -e
export GOOS=darwin
export GOARCH=amd64
export PROFILE="dev"
export PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for release env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-07-12 16:34
# FILE : test.sh
# ******************************************************
set -e
export GOOS=darwin
export GOARCH=amd64
export PROFILE="release"
export PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for test env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-07-12 16:34
# FILE : test.sh
# ******************************************************
set -e
export GOOS=darwin
export GOARCH=amd64
export PROFILE="test"
export PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for dev env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2017-10-18 13:24
# FILE : dev.sh
# ******************************************************
set -e
export GOOS=linux
export GOARCH=amd64
export PROFILE="dev"
PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
#!/usr/bin/env bash
# ******************************************************
# DESC : build script for release env
# AUTHOR : Alex Stocks
# VERSION : 1.0
# LICENCE : Apache License 2.0
# EMAIL : alexstocks@foxmail.com
# MOD : 2016-07-12 16:34
# FILE : test.sh
# ******************************************************
set -e
export GOOS=windows
export GOARCH=amd64
export PROFILE="release"
export PROJECT_HOME=`pwd`
if [ -f "${PROJECT_HOME}/assembly/common/app.properties" ]; then
. ${PROJECT_HOME}/assembly/common/app.properties
fi
if [ -f "${PROJECT_HOME}/assembly/common/build.sh" ]; then
sh ${PROJECT_HOME}/assembly/common/build.sh
fi
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment