@ -0,0 +1,79 @@ | |||||
# 接口 | |||||
```bash | |||||
IP: 192.168.100.50 | |||||
PORT: 8000 | |||||
HOST: baidu-link-submit-ms.juejin.im | |||||
``` | |||||
## 资源创建通知 | |||||
### 请求 | |||||
`POST /v1/events/created` | |||||
### 参数 | |||||
```bash | |||||
# 格式 | |||||
Content-Type: application/json; charset=utf-8 | |||||
{ | |||||
type, | |||||
id | |||||
} | |||||
``` | |||||
```bash | |||||
# 说明 | |||||
type := 'link' | 'column' | |||||
# type -> 资源类型,必需 | |||||
# link -> 链接 | |||||
# column -> 专栏 | |||||
id := <string> | |||||
# id -> 资源 ID,必需 | |||||
``` | |||||
### 响应 | |||||
```bash | |||||
{ | |||||
"s": 1, | |||||
"m": "success", | |||||
"d": [] | |||||
} | |||||
``` | |||||
### 示例 | |||||
```bash | |||||
# 专栏文章创建后 | |||||
POST http://192.168.100.50:8000/v1/events/created HTTP/1.1 | |||||
Host: baidu-link-submit-ms.juejin.im | |||||
Content-Type: application/json | |||||
{ | |||||
"type": "column", | |||||
"id": "5ac9dc9af265da23884d5543" | |||||
} | |||||
``` | |||||
## 资源更新通知 | |||||
### 请求 | |||||
`POST /v1/events/updated` | |||||
其余同上。 | |||||
## 资源删除通知 | |||||
### 请求 | |||||
`POST /v1/events/deleted` | |||||
其余同上。 |
@ -1,2 +1 @@ | |||||
# hi-guoqian-go-ms | |||||
guoqian Go->redis |
@ -0,0 +1,58 @@ | |||||
# baidu_link_submit_ms.private.conf | |||||
# baidu_link_submit_ms nginx config file. | |||||
# | |||||
# This file auto generated by baidu_link_submit_ms/scripts/init_config.sh, | |||||
# [WARRING!] DO NOT change this manualy. | |||||
# | |||||
# @version 170227:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
upstream baidu_link_submit_ms_private { | |||||
server 127.0.0.1:10100; | |||||
keepalive 64; | |||||
} | |||||
server { | |||||
listen 8000; | |||||
server_name baidu-link-submit-ms.juejin.im; | |||||
default_type 'text/plain'; # or browser will download page | |||||
include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||||
root /data/repo/baidu_link_submit_ms; | |||||
access_log /data/repo/baidu_link_submit_ms/logs/nginx-access.public.log logstash; | |||||
error_log /data/repo/baidu_link_submit_ms/logs/nginx-error.public.log; | |||||
client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||||
proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||||
# X-Juejin-Src for api src trace back | |||||
# X-Juejin-Uid for non-login user id | |||||
# X-Juejin-Token for api param hash check | |||||
add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||||
if ($request_method = OPTIONS ) { | |||||
return 200; | |||||
} | |||||
# global location settings | |||||
location /status { | |||||
return 200; | |||||
} | |||||
location / { | |||||
proxy_set_header X-Real-IP $remote_addr; | |||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||||
proxy_set_header Host $http_host; | |||||
proxy_set_header X-Nginx-Proxy true; | |||||
proxy_pass http://baidu_link_submit_ms_private; | |||||
} | |||||
location ~ /\. { | |||||
deny all; | |||||
access_log off; | |||||
log_not_found off; | |||||
} | |||||
} |
@ -0,0 +1,58 @@ | |||||
# baidu_link_submit_ms.public.conf | |||||
# baidu_link_submit_ms nginx config file. | |||||
# | |||||
# This file auto generated by baidu_link_submit_ms/scripts/init_config.sh, | |||||
# [WARRING!] DO NOT change this manualy. | |||||
# | |||||
# @version 170227:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
upstream baidu_link_submit_ms_public { | |||||
server 127.0.0.1:10100; | |||||
keepalive 64; | |||||
} | |||||
server { | |||||
listen 80; | |||||
server_name baidu-link-submit-ms.juejin.im; | |||||
default_type 'text/plain'; # or browser will download page | |||||
include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||||
root /data/repo/baidu_link_submit_ms; | |||||
access_log /data/repo/baidu_link_submit_ms/logs/nginx-access.public.log logstash; | |||||
error_log /data/repo/baidu_link_submit_ms/logs/nginx-error.public.log; | |||||
client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||||
proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||||
# X-Juejin-Src for api src trace back | |||||
# X-Juejin-Uid for non-login user id | |||||
# X-Juejin-Token for api param hash check | |||||
add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||||
if ($request_method = OPTIONS ) { | |||||
return 200; | |||||
} | |||||
# global location settings | |||||
location /status { | |||||
return 200; | |||||
} | |||||
location / { | |||||
proxy_set_header X-Real-IP $remote_addr; | |||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||||
proxy_set_header Host $http_host; | |||||
proxy_set_header X-Nginx-Proxy true; | |||||
proxy_pass http://baidu_link_submit_ms_public; | |||||
} | |||||
location ~ /\. { | |||||
deny all; | |||||
access_log off; | |||||
log_not_found off; | |||||
} | |||||
} |
@ -0,0 +1 @@ | |||||
1 |
@ -0,0 +1,12 @@ | |||||
[Unit] | |||||
Description = Micro Service API | |||||
After = syslog.target network.target | |||||
[Service] | |||||
PIDFile = /data/repo/baidu_link_submit_ms/lock/baidu_link_submit_ms.pid | |||||
ExecStart = /data/repo/baidu_link_submit_ms/bin/baidu_link_submit_ms beta | |||||
ExecReload = /data/repo/baidu_link_submit_ms/bin/baidu_link_submit_ms beta reload | |||||
ExecStop = /data/repo/baidu_link_submit_ms/bin/baidu_link_submit_ms beta stop | |||||
[Install] | |||||
WantedBy=multi-user.target |
@ -0,0 +1 @@ | |||||
1 |
@ -0,0 +1,82 @@ | |||||
#!/bin/sh | |||||
# ci.sh | |||||
# This script for build go projects. | |||||
# @version 170327:2 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
# [ci] | |||||
echo "-[ci]-" | |||||
echo "start" | |||||
# ----------------------------[manual config here]------------------------------ | |||||
# base config | |||||
REPO_SRC=/data/repo/baidu_link_submit_ms | |||||
BUILD_TARGET=baidu_link_submit_ms | |||||
# fetch source config | |||||
go_packages=( | |||||
"github.com/astaxie/beego" | |||||
) | |||||
http_proxy="" | |||||
# deploy config | |||||
DEPLOY_SRC=/data/repo | |||||
DEPLOY_LOG_SRC=/data/logs | |||||
ACTION=$1 | |||||
RELEASE_ENV=$2 | |||||
DEV_ENV_LOCATION=( | |||||
"root@192.168.0.203" | |||||
) | |||||
BETA_ENV_LOCATION=( | |||||
"root@192.168.0.222" | |||||
) | |||||
ONLINE_ENV_LOCATION=( | |||||
"root@192.168.100.42" # microservice03v | |||||
"root@192.168.100.44" # microservice04v | |||||
"root@192.168.100.46" # microservice04v | |||||
) | |||||
# ------------------------------------------------------------------------------ | |||||
# check if release env fit repo src | |||||
NOW_PWD=`pwd` | |||||
if [ "$NOW_PWD" != "${REPO_SRC}/scripts" ] && [ "$NOW_PWD" != "${REPO_SRC}" ]; then | |||||
echo -e "\033[43m[WARRING!] PWD is ${NOW_PWD}, but REPO_SRC is ${REPO_SRC} \033[0m"; | |||||
echo -e "please check your REPO_SRC config to make sure that you config this file correctly."; | |||||
exit 1; | |||||
fi | |||||
# run scripts | |||||
SCRIPTS_SRC="${REPO_SRC}/scripts/ci" | |||||
if [ "${ACTION}" == "build" ]; then | |||||
. "${SCRIPTS_SRC}/fetch_source.sh" | |||||
. "${SCRIPTS_SRC}/build.sh" | |||||
elif [ "${ACTION}" == "release" ]; then | |||||
. "${SCRIPTS_SRC}/fetch_source.sh" | |||||
. "${SCRIPTS_SRC}/build.sh" | |||||
. "${SCRIPTS_SRC}/deploy.sh" | |||||
elif [ "${ACTION}" == "run_bee" ]; then | |||||
. "${SCRIPTS_SRC}/run_bee.sh" | |||||
else | |||||
echo "usage:" | |||||
echo "./ci.sh [action: build/release/run_bee] [beta/online/bee_path]" | |||||
echo "" | |||||
echo "e.g." | |||||
echo "./ci.sh release beta" | |||||
echo "" | |||||
fi | |||||
echo "end" | |||||
@ -0,0 +1,72 @@ | |||||
#!/bin/sh | |||||
# build.sh | |||||
# This script for build go projects. | |||||
# @version 170227:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
# [config] | |||||
echo "-[config]-" | |||||
# ----------------------------[manual config here]------------------------------ | |||||
# REPO_SRC=/data/repo/collection_set_api | |||||
# BUILD_TARGET=collection_set_api | |||||
# ------------------------------------------------------------------------------ | |||||
echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||||
echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||||
echo "" | |||||
sleep 1 | |||||
# [set env] | |||||
echo "-[set env]-" | |||||
# $GOBIN | |||||
export GOBIN="${REPO_SRC}/bin" | |||||
echo -e "\033[34mGOBIN set to: ${GOBIN}\033[0m" | |||||
# $GOPATH | |||||
export GOPATH="${REPO_SRC}" | |||||
echo -e "\033[34mGOPATH set to: ${GOPATH}\033[0m" | |||||
echo "" | |||||
sleep 1 | |||||
# [check old build target] | |||||
echo "-[check old build target]-" | |||||
if [ ! -d $GOBIN ]; then mkdir $GOBIN; fi | |||||
if [ -f "${GOBIN}/${BUILD_TARGET}" ]; then | |||||
echo -e "\033[43m[WARRING!] build target alerady exists, will remove it. \033[0m"; | |||||
echo "old build_target detail:" | |||||
ls -alh "${GOBIN}/${BUILD_TARGET}"; | |||||
oldShaSum=`shasum "${GOBIN}/${BUILD_TARGET}" | awk -F' ' '{print $1}'`; | |||||
echo "target sha: ${oldShaSum}"; | |||||
rm -rf "${GOBIN}/${BUILD_TARGET}"; | |||||
echo "old build target removed."; | |||||
fi | |||||
echo "done." | |||||
echo "" | |||||
sleep 1 | |||||
# [build] | |||||
echo "-[build]-" | |||||
echo "build start: " | |||||
echo "go build -o ${GOBIN}/${BUILD_TARGET}" | |||||
cd "${GOPATH}/src" | |||||
go build -o "${GOBIN}/${BUILD_TARGET}" | |||||
ls -alh "${GOBIN}/${BUILD_TARGET}" | |||||
newShaSum=`shasum "${GOBIN}/${BUILD_TARGET}" | awk -F' ' '{print $1}'`; | |||||
echo "target sha: ${newShaSum}"; | |||||
if [ "$oldShaSum" == "$newShaSum" ];then | |||||
echo -e "\033[43m[WARRING!] old build target shasum is equals to new build target. \033[0m" | |||||
fi | |||||
echo "done." | |||||
@ -0,0 +1,181 @@ | |||||
#!/bin/sh | |||||
# deploy.sh | |||||
# This script deploy repo to target env. | |||||
# @version 170322:2 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
# [start deploy] | |||||
echo "-[start deploy]-" | |||||
# ----------------------------[manual config here]------------------------------ | |||||
# REPO_SRC=/data/repo/collection_set_api | |||||
# BUILD_TARGET=collection_set_api | |||||
# DEPLOY_SRC=/data/repo | |||||
# DEPLOY_LOG_SRC=/data/logs | |||||
# RELEASE_ENV=$1 | |||||
# | |||||
# DEV_ENV_LOCATION=( | |||||
# "root@192.168.0.203" | |||||
# ) | |||||
# BETA_ENV_LOCATION=( | |||||
# "root@192.168.0.204" | |||||
# ) | |||||
# ONLINE_ENV_LOCATION=( | |||||
# "root@192.168.100.32" # microservice03v | |||||
# "root@192.168.100.28" # microservice04v | |||||
# ) | |||||
# ------------------------------------------------------------------------------ | |||||
# final release location | |||||
RELEASE_ENV_LOCATION="" | |||||
# release file temp storage location | |||||
RELEASE_TEMP_DIR=/data/repo/release | |||||
# program system service name for systemctl | |||||
SERVICE_NAME="${BUILD_TARGET}.service" | |||||
# final deploy src | |||||
FINAL_DEPLOY_SRC="${DEPLOY_SRC}/${BUILD_TARGET}" | |||||
# nginx config | |||||
NGINX_BIN_LOCATION="/data/apps/nginx/sbin/nginx" | |||||
NGINX_CONFIG_LOCATION="/data/apps/nginx/conf/vhost/" | |||||
# deploy target machine error handler config | |||||
DEPLOY_ERROR_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_error.s" | |||||
DEPLOY_SUCCESS_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_success.s" | |||||
DEPLOY_LOG="${FINAL_DEPLOY_SRC}/logs/deploy.log" | |||||
# print config | |||||
echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||||
echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||||
echo -e "\033[34mRELEASE_TEMP_DIR set to: ${RELEASE_TEMP_DIR}\033[0m" | |||||
echo -e "\033[34mPROJECT WILL DEPLOY TO: ${FINAL_DEPLOY_SRC}\033[0m" | |||||
echo -e "\033[34mSERVICE_NAME set to: ${SERVICE_NAME}\033[0m" | |||||
echo "" | |||||
sleep 2 | |||||
# [check input] | |||||
if [ "$RELEASE_ENV" == "dev" ]; then | |||||
RELEASE_ENV_LOCATION=${DEV_ENV_LOCATION[*]} | |||||
elif [ "$RELEASE_ENV" == "beta" ]; then | |||||
RELEASE_ENV_LOCATION=${BETA_ENV_LOCATION[*]} | |||||
elif [ "$RELEASE_ENV" == "online" ]; then | |||||
RELEASE_ENV_LOCATION=${ONLINE_ENV_LOCATION[*]} | |||||
else | |||||
RELEASE_ENV_LOCATION="" | |||||
fi | |||||
if [ "$RELEASE_ENV_LOCATION" == "" ]; then | |||||
echo "please input an avaliable deploy environment [dev/beta/online]"; | |||||
echo "example: ./deploy.sh beta"; | |||||
exit 1; | |||||
fi | |||||
echo -e "\033[34mRELEASE_ENV set to: ${RELEASE_ENV} \033[0m" | |||||
echo -e "\033[34mRELEASE_ENV_LOCATION set to: \033[0m" | |||||
for releaseLocation in ${RELEASE_ENV_LOCATION[*]}; | |||||
do | |||||
echo -e "\033[34m ${releaseLocation} \033[0m" | |||||
done | |||||
echo "" | |||||
sleep 1 | |||||
# [check old release file] | |||||
echo "-[check old release target]-" | |||||
if [ ! -d $RELEASE_TEMP_DIR ]; then mkdir $RELEASE_TEMP_DIR; fi | |||||
if [ -f "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" ]; then | |||||
echo -e "\033[43m[WARRING!] release target alerady exists, will remove it. \033[0m"; | |||||
ls -alh "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz"; | |||||
oldShaSum=`shasum "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" | awk -F' ' '{print $1}'`; | |||||
echo "target sha: ${oldShaSum}"; | |||||
rm -f "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz"; | |||||
echo "old build target removed."; | |||||
fi | |||||
echo "" | |||||
sleep 1 | |||||
# [compress new release file] | |||||
echo "-[compress new release file]-" | |||||
cd $REPO_SRC; | |||||
tar -zcf "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" "./" | |||||
ls -alh "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz"; | |||||
newShaSum=`shasum "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" | awk -F' ' '{print $1}'`; | |||||
echo "target sha: ${newShaSum}"; | |||||
if [ "$oldShaSum" == "$newShaSum" ];then | |||||
echo -e "\033[43m[WARRING!] old release target shasum is equals to new release target. \033[0m" | |||||
fi | |||||
echo "" | |||||
sleep 1 | |||||
# [deploy] | |||||
echo "-[deploy]-" | |||||
echo "- coyp to target machine" | |||||
for releaseLocation in ${RELEASE_ENV_LOCATION[*]}; | |||||
do | |||||
echo -e "\033[34m deploy to ${releaseLocation} \033[0m"; | |||||
ssh -T $releaseLocation <<DEPLOY_INIT_SCRIPTS_1 | |||||
if [ ! -d $FINAL_DEPLOY_SRC ]; then mkdir $FINAL_DEPLOY_SRC; fi | |||||
if [ -f ${FINAL_DEPLOY_SRC}/${BUILD_TARGET}.tar.gz ]; then | |||||
rm -f ${FINAL_DEPLOY_SRC}/${BUILD_TARGET}.tar.gz; | |||||
fi | |||||
DEPLOY_INIT_SCRIPTS_1 | |||||
scp "${RELEASE_TEMP_DIR}/${BUILD_TARGET}.tar.gz" "${releaseLocation}:${FINAL_DEPLOY_SRC}/"; | |||||
ssh -T $releaseLocation <<DEPLOY_INIT_SCRIPTS_2 | |||||
cd "${FINAL_DEPLOY_SRC}/"; | |||||
tar -zxvf "./${BUILD_TARGET}.tar.gz"; | |||||
DEPLOY_INIT_SCRIPTS_2 | |||||
done | |||||
echo "done." | |||||
echo "" | |||||
echo "-[configure & reactive service]-" | |||||
i=0 | |||||
for releaseLocation in ${RELEASE_ENV_LOCATION[*]}; | |||||
do | |||||
# sleep for online lvs reconnect nginx | |||||
if [ "$i" != "0" ]; then | |||||
echo "sleep 120 seconds for online lvs reconnect nginx."; | |||||
sleep 120; | |||||
fi | |||||
# deploy start | |||||
echo -e "\033[34mconfigure ${releaseLocation} \033[0m" | |||||
ssh -T $releaseLocation <<DEPLOY_SCRIPTS_1 | |||||
# exec reactive scripts | |||||
chmod +x "${FINAL_DEPLOY_SRC}/scripts/ci/reactive_service.sh"; | |||||
bash "${FINAL_DEPLOY_SRC}/scripts/ci/reactive_service.sh" ${REPO_SRC} ${BUILD_TARGET} ${DEPLOY_SRC} ${DEPLOY_LOG_SRC} ${RELEASE_ENV}; | |||||
DEPLOY_SCRIPTS_1 | |||||
#check deploy result | |||||
isDeploySuccess="" | |||||
isDeploySuccess=`ssh -T $releaseLocation <<DEPLOY_SCRIPTS_2 | |||||
cat $DEPLOY_SUCCESS_SIGNAL_FILE | |||||
DEPLOY_SCRIPTS_2` | |||||
if [ "${isDeploySuccess}" != "success" ]; then | |||||
echo -e "\033[43m[ERROR!] deploy failed detected. Failed at : ${releaseLocation}\033[0m"; | |||||
echo "please check release log at : ${releaseLocation}${DEPLOY_LOG}"; | |||||
echo "script exit."; | |||||
exit 1; | |||||
else | |||||
echo -e "\033[32m[OK] deploy success. deploy at : ${releaseLocation}\033[0m"; | |||||
fi | |||||
# counter | |||||
i=$(expr "$i" + "1"); | |||||
done | |||||
echo "done."; | |||||
exit 0; | |||||
@ -0,0 +1,71 @@ | |||||
#!/bin/sh | |||||
# fetch_source.sh | |||||
# This script for fetch source and packages. | |||||
# @version 170227:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
# [config] | |||||
echo "-[config]-" | |||||
# ----------------------------[manual config here]------------------------------ | |||||
# REPO_SRC=/data/repo/collection_set_api | |||||
go_packages=( | |||||
"github.com/astaxie/beego" | |||||
"github.com/garyburd/redigo/redis" | |||||
) | |||||
# | |||||
# http_proxy="http://localhost:8123" | |||||
# ------------------------------------------------------------------------------ | |||||
# init env | |||||
# $GOBIN | |||||
export GOBIN="${REPO_SRC}/bin" | |||||
echo -e "\033[34mGOBIN set to: ${GOBIN}\033[0m" | |||||
# $GOPATH | |||||
export GOPATH="${REPO_SRC}" | |||||
echo -e "\033[34mGOPATH set to: ${GOPATH}\033[0m" | |||||
# print package list | |||||
echo "package list:" | |||||
for pkg in ${go_packages[*]}; | |||||
do | |||||
echo -e "\033[34m${pkg}\033[0m"; | |||||
done | |||||
echo "" | |||||
if [ "$http_proxy" != "" ]; then | |||||
echo "http_proxy set to:" | |||||
echo -e "\033[34m${http_proxy}\033[0m"; | |||||
echo "http_proxy location info:" | |||||
proxyLocation=`http_proxy=${http_proxy} curl -s ip.gs` | |||||
echo -e "\033[34m${proxyLocation}\033[0m"; | |||||
fi | |||||
echo "" | |||||
sleep 1 | |||||
# [fetch] | |||||
echo "-[fetch package]-" | |||||
for pkg in ${go_packages[*]}; | |||||
do | |||||
if [ "$http_proxy" == "" ]; then | |||||
echo "go get ${pkg}"; | |||||
go get $pkg; | |||||
else | |||||
echo "http_proxy=${http_proxy} go get ${pkg}"; | |||||
http_proxy=${http_proxy} go get $pkg; | |||||
fi | |||||
done | |||||
echo "done." |
@ -0,0 +1,183 @@ | |||||
#!/bin/sh | |||||
# reactive_service.sh | |||||
# This script for reactive this projects. | |||||
# @version 170327:3 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
# [config] | |||||
echo "-[config]-" | |||||
# ----------------------------[manual config here]------------------------------ | |||||
REPO_SRC=$1 | |||||
BUILD_TARGET=$2 | |||||
DEPLOY_SRC=$3 | |||||
DEPLOY_LOG_SRC=$4 | |||||
RELEASE_ENV=$5 | |||||
# ------------------------------------------------------------------------------ | |||||
# program system service name for systemctl | |||||
SERVICE_NAME="${BUILD_TARGET}.service" | |||||
# final deploy src | |||||
FINAL_DEPLOY_SRC="${DEPLOY_SRC}/${BUILD_TARGET}" | |||||
# nginx config | |||||
NGINX_BIN_LOCATION="/data/apps/nginx/sbin/nginx" | |||||
NGINX_CONFIG_LOCATION="/data/apps/nginx/conf/vhost/" | |||||
# deploy target machine error handler config | |||||
DEPLOY_ERROR_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_error.s" | |||||
DEPLOY_SUCCESS_SIGNAL_FILE="${FINAL_DEPLOY_SRC}/logs/deploy_success.s" | |||||
DEPLOY_LOG="${FINAL_DEPLOY_SRC}/logs/deploy.log" | |||||
# print config | |||||
echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||||
echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||||
echo -e "\033[34mPROJECT WILL DEPLOY TO: ${FINAL_DEPLOY_SRC}\033[0m" | |||||
echo -e "\033[34mSERVICE_NAME set to: ${SERVICE_NAME}\033[0m" | |||||
echo "" | |||||
sleep 2 | |||||
# [check input] | |||||
if [ "$RELEASE_ENV" == "dev" ]; then | |||||
echo "env ok"; | |||||
elif [ "$RELEASE_ENV" == "beta" ]; then | |||||
echo "env ok"; | |||||
elif [ "$RELEASE_ENV" == "online" ]; then | |||||
echo "env ok"; | |||||
else | |||||
echo "please input an avaliable deploy environment [dev/beta/online]"; | |||||
echo "example: ./deploy.sh beta"; | |||||
exit 1; | |||||
fi | |||||
echo -e "\033[34mRELEASE_ENV set to: ${RELEASE_ENV} \033[0m" | |||||
echo "" | |||||
sleep 1 | |||||
# configure log | |||||
if [ ! -d "${DEPLOY_LOG_SRC}/${BUILD_TARGET}" ]; then mkdir "${DEPLOY_LOG_SRC}/${BUILD_TARGET}"; fi | |||||
if [ ! -L "${FINAL_DEPLOY_SRC}/logs" ]; then ln -s "${DEPLOY_LOG_SRC}/${BUILD_TARGET}" "${FINAL_DEPLOY_SRC}/logs"; fi | |||||
# remove old deploy signal | |||||
if [ -f "${DEPLOY_ERROR_SIGNAL_FILE}" ]; then rm -f "${DEPLOY_ERROR_SIGNAL_FILE}"; fi | |||||
if [ -f "${DEPLOY_SUCCESS_SIGNAL_FILE}" ]; then rm -f "${DEPLOY_SUCCESS_SIGNAL_FILE}"; fi | |||||
# deploy start | |||||
echo "" | tee -a $DEPLOY_LOG; | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "deploy start" | tee -a $DEPLOY_LOG; | |||||
# configure service | |||||
if [ ! -L "/etc/systemd/system/${SERVICE_NAME}" ]; then | |||||
cp "${FINAL_DEPLOY_SRC}/config/systemctl/${SERVICE_NAME}" "/etc/systemd/system/${SERVICE_NAME}"; | |||||
else | |||||
rm -f "/etc/systemd/system/${SERVICE_NAME}"; | |||||
cp "${FINAL_DEPLOY_SRC}/config/systemctl/${SERVICE_NAME}" "/etc/systemd/system/${SERVICE_NAME}"; | |||||
fi | |||||
# configure nginx | |||||
PUBLIC_NGINX_CONF="${FINAL_DEPLOY_SRC}/config/nginx/${BUILD_TARGET}.public.conf" | |||||
PRIVATE_NGINX_CONF="${FINAL_DEPLOY_SRC}/config/nginx/${BUILD_TARGET}.private.conf" | |||||
if [ -f "${PUBLIC_NGINX_CONF}" ]; then | |||||
ln -s "${PUBLIC_NGINX_CONF}" $NGINX_CONFIG_LOCATION; | |||||
fi | |||||
if [ -f "${PRIVATE_NGINX_CONF}" ]; then | |||||
ln -s "${PRIVATE_NGINX_CONF}" $NGINX_CONFIG_LOCATION; | |||||
fi | |||||
# test nginx config | |||||
$NGINX_BIN_LOCATION -t 2> "${FINAL_DEPLOY_SRC}/logs/nginx_test.log"; | |||||
isNginxOk=`grep 'test is successful' "${FINAL_DEPLOY_SRC}/logs/nginx_test.log" | wc -l `; | |||||
if [ "$isNginxOk" != "1" ]; then | |||||
touch $DEPLOY_ERROR_SIGNAL_FILE; | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "[ERROR!] deploy error with nginx config error, nginx config error is : " | tee -a $DEPLOY_LOG; | |||||
cat "${FINAL_DEPLOY_SRC}/logs/nginx_test.log" | tee -a $DEPLOY_LOG; | |||||
exit 1; | |||||
else | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "nginx config is ok:" | tee -a $DEPLOY_LOG; | |||||
cat "${FINAL_DEPLOY_SRC}/logs/nginx_test.log" | tee -a $DEPLOY_LOG; | |||||
fi | |||||
# stop nginx | |||||
$NGINX_BIN_LOCATION -s stop | |||||
# check nginx is stoped | |||||
sleep 20; | |||||
nginxNum=`ps auxw | grep --color 'nginx' | grep -v grep | wc -l` | |||||
if [ "$nginxNum" != "0" ]; then | |||||
touch $DEPLOY_ERROR_SIGNAL_FILE; | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "[ERROR!] deploy error with nginx stop failed, nginx process num is : ${nginxNum}" | tee -a $DEPLOY_LOG; | |||||
exit 1; | |||||
else | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "nginx stopped" | tee -a $DEPLOY_LOG; | |||||
fi | |||||
# restart service | |||||
/usr/bin/systemctl daemon-reload; | |||||
/usr/bin/systemctl enable ${SERVICE_NAME}; | |||||
/usr/bin/systemctl stop ${BUILD_TARGET}; # use start-stop for first time deploy | |||||
/usr/bin/systemctl start ${BUILD_TARGET}; | |||||
# check service | |||||
sleep 2; | |||||
/usr/bin/systemctl status "${BUILD_TARGET}" > "${FINAL_DEPLOY_SRC}/logs/service_status.log"; | |||||
serviceStatus=`grep "Active: active" "${FINAL_DEPLOY_SRC}/logs/service_status.log" | wc -l`; | |||||
if [ "$serviceStatus" == "0" ]; then | |||||
touch $DEPLOY_ERROR_SIGNAL_FILE; | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "[ERROR!] deploy error with service start failed, systemctl status :" | tee -a $DEPLOY_LOG; | |||||
cat "${FINAL_DEPLOY_SRC}/logs/service_status.log" | tee -a $DEPLOY_LOG; | |||||
# restart nginx | |||||
$NGINX_BIN_LOCATION; | |||||
# check nginx num | |||||
nginxNum=`ps auxw | grep --color 'nginx' | grep -v grep | wc -l` | |||||
sleep 5; | |||||
if [ "$nginxNum" == "0" ]; then | |||||
touch $DEPLOY_ERROR_SIGNAL_FILE; | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "[ERROR!] deploy error with nginx start failed, nginx process num is : ${nginxNum}" | tee -a $DEPLOY_LOG; | |||||
exit 1; | |||||
else | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "nginx started" | tee -a $DEPLOY_LOG; | |||||
fi | |||||
exit 1; | |||||
else | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "service started" | tee -a $DEPLOY_LOG; | |||||
cat "${FINAL_DEPLOY_SRC}/logs/service_status.log" | tee -a $DEPLOY_LOG; | |||||
fi | |||||
# start nginx | |||||
$NGINX_BIN_LOCATION | |||||
# check nginx num | |||||
nginxNum=`ps auxw | grep --color 'nginx' | grep -v grep | wc -l`; | |||||
sleep 5; | |||||
if [ "$nginxNum" == "0" ]; then | |||||
touch $DEPLOY_ERROR_SIGNAL_FILE; | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "[ERROR!] deploy error with nginx start failed, nginx process num is : ${nginxNum}" | tee -a $DEPLOY_LOG; | |||||
exit 1; | |||||
else | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "nginx started" | tee -a $DEPLOY_LOG; | |||||
fi | |||||
# deploy success | |||||
echo "success" > $DEPLOY_SUCCESS_SIGNAL_FILE; | |||||
echo -e "`date "+%Y-%m-%d %H:%M:%S"` \c" | tee -a $DEPLOY_LOG; | |||||
echo "[OK] deploy success." | tee -a $DEPLOY_LOG; | |||||
exit 0; |
@ -0,0 +1,51 @@ | |||||
#!/bin/sh | |||||
# run_bee.sh | |||||
# This script for run beego projects for dev. | |||||
# @version 170227:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
# [config] | |||||
echo "-[config]-" | |||||
# ----------------------------[manual config here]------------------------------ | |||||
# REPO_SRC=/data/repo/collection_set_api | |||||
# BUILD_TARGET=collection_set_api | |||||
BEE_PATH=$2 | |||||
# ------------------------------------------------------------------------------ | |||||
echo -e "\033[34mREPO_SRC set to: ${REPO_SRC}\033[0m" | |||||
echo -e "\033[34mBUILD_TARGET set to: ${BUILD_TARGET}\033[0m" | |||||
echo "" | |||||
sleep 1 | |||||
# [set env] | |||||
echo "-[set env]-" | |||||
# $GOBIN | |||||
export GOBIN="${REPO_SRC}/bin" | |||||
echo -e "\033[34mGOBIN set to: ${GOBIN}\033[0m" | |||||
# $GOPATH | |||||
export GOPATH="${REPO_SRC}" | |||||
echo -e "\033[34mGOPATH set to: ${GOPATH}\033[0m" | |||||
echo "" | |||||
# run | |||||
if [ "${BEE_PATH}" == "" ]; then | |||||
echo "please input bee executable file loacation to run this scripts, like :" | |||||
echo "./ci.sh run_bee /data/bin/bee" | |||||
exit 1; | |||||
fi | |||||
`${BEE_PATH} run ${REPO_SRC}/src` | |||||
echo "done." | |||||
@ -0,0 +1,58 @@ | |||||
# REPO_NAME.private.conf | |||||
# REPO_NAME nginx config file. | |||||
# | |||||
# This file auto generated by REPO_NAME/scripts/init_config.sh, | |||||
# [WARRING!] DO NOT change this manualy. | |||||
# | |||||
# @version 170227:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
upstream REPO_NAME_private { | |||||
server UPSTREAM_ADDR; | |||||
keepalive 64; | |||||
} | |||||
server { | |||||
listen 8000; | |||||
server_name DOMAIN_NAME; | |||||
default_type 'text/plain'; # or browser will download page | |||||
include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||||
root /data/repo/REPO_NAME; | |||||
access_log /data/repo/REPO_NAME/logs/nginx-access.public.log logstash; | |||||
error_log /data/repo/REPO_NAME/logs/nginx-error.public.log; | |||||
client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||||
proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||||
# X-Juejin-Src for api src trace back | |||||
# X-Juejin-Uid for non-login user id | |||||
# X-Juejin-Token for api param hash check | |||||
add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||||
if ($request_method = OPTIONS ) { | |||||
return 200; | |||||
} | |||||
# global location settings | |||||
location /status { | |||||
return 200; | |||||
} | |||||
location / { | |||||
proxy_set_header X-Real-IP $remote_addr; | |||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||||
proxy_set_header Host $http_host; | |||||
proxy_set_header X-Nginx-Proxy true; | |||||
proxy_pass http://REPO_NAME_private; | |||||
} | |||||
location ~ /\. { | |||||
deny all; | |||||
access_log off; | |||||
log_not_found off; | |||||
} | |||||
} |
@ -0,0 +1,58 @@ | |||||
# REPO_NAME.public.conf | |||||
# REPO_NAME nginx config file. | |||||
# | |||||
# This file auto generated by REPO_NAME/scripts/init_config.sh, | |||||
# [WARRING!] DO NOT change this manualy. | |||||
# | |||||
# @version 170227:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
upstream REPO_NAME_public { | |||||
server UPSTREAM_ADDR; | |||||
keepalive 64; | |||||
} | |||||
server { | |||||
listen 80; | |||||
server_name DOMAIN_NAME; | |||||
default_type 'text/plain'; # or browser will download page | |||||
include /data/apps/nginx/conf/origin/gold.xitu.io_and_juejin.im.conf; | |||||
root /data/repo/REPO_NAME; | |||||
access_log /data/repo/REPO_NAME/logs/nginx-access.public.log logstash; | |||||
error_log /data/repo/REPO_NAME/logs/nginx-error.public.log; | |||||
client_body_temp_path /data/logs/nginx/client_body_temp/ 1 2; | |||||
proxy_temp_path /data/logs/nginx/proxy_temp/ 1 2; | |||||
# X-Juejin-Src for api src trace back | |||||
# X-Juejin-Uid for non-login user id | |||||
# X-Juejin-Token for api param hash check | |||||
add_header 'Access-Control-Allow-Headers' 'X-Juejin-Src,X-Juejin-Uid,X-Juejin-Token' always; | |||||
if ($request_method = OPTIONS ) { | |||||
return 200; | |||||
} | |||||
# global location settings | |||||
location /status { | |||||
return 200; | |||||
} | |||||
location / { | |||||
proxy_set_header X-Real-IP $remote_addr; | |||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||||
proxy_set_header Host $http_host; | |||||
proxy_set_header X-Nginx-Proxy true; | |||||
proxy_pass http://REPO_NAME_public; | |||||
} | |||||
location ~ /\. { | |||||
deny all; | |||||
access_log off; | |||||
log_not_found off; | |||||
} | |||||
} |
@ -0,0 +1,12 @@ | |||||
[Unit] | |||||
Description = Micro Service API | |||||
After = syslog.target network.target | |||||
[Service] | |||||
PIDFile = /data/repo/REPO_NAME/lock/BUILD_TARGET.pid | |||||
ExecStart = /data/repo/REPO_NAME/bin/BUILD_TARGET beta | |||||
ExecReload = /data/repo/REPO_NAME/bin/BUILD_TARGET beta reload | |||||
ExecStop = /data/repo/REPO_NAME/bin/BUILD_TARGET beta stop | |||||
[Install] | |||||
WantedBy=multi-user.target |
@ -0,0 +1,12 @@ | |||||
[Unit] | |||||
Description = Micro Service API | |||||
After = syslog.target network.target | |||||
[Service] | |||||
PIDFile = /data/repo/REPO_NAME/lock/BUILD_TARGET.pid | |||||
ExecStart = /data/repo/REPO_NAME/bin/BUILD_TARGET online | |||||
ExecReload = /data/repo/REPO_NAME/bin/BUILD_TARGET online reload | |||||
ExecStop = /data/repo/REPO_NAME/bin/BUILD_TARGET online stop | |||||
[Install] | |||||
WantedBy=multi-user.target |
@ -0,0 +1,145 @@ | |||||
#!/bin/bash | |||||
# init_config.sh | |||||
# init enviroment config scripts. | |||||
# @version 170322:1 | |||||
# @author zhangxuhong <zhangxuhong@xitu.io> | |||||
# | |||||
# ----------------------------[manual config here]------------------------------ | |||||
# base config | |||||
REPO_SRC=/data/repo/baidu_link_submit_ms | |||||
REPO_NAME=baidu_link_submit_ms | |||||
BUILD_TARGET="${REPO_NAME}" | |||||
RELEASE_ENV=$1 # test, beta, online | |||||
# nginx config file type | |||||
DOMAIN_NAME="baidu-link-submit-ms.juejin.im" | |||||
PUBLIC_UPSTREAM_PORT=13100 | |||||
PRIVATE_UPSTREAM_PORT=13100 | |||||
# ------------------------------------------------------------------------------ | |||||
# default config | |||||
NGINX_CONF_TMPL_PUBLIC="REPO_NAME.public.conf" | |||||
NGINX_CONF_TMPL_PRIVATE="REPO_NAME.private.conf" | |||||
SYSTEMCTL_CONF_TMPL_BETA="REPO_NAME.beta.service" | |||||
SYSTEMCTL_CONF_TMPL_RELEASE="REPO_NAME.online.service" | |||||
# auto generated config | |||||
# nginx | |||||
NGINX_CONFIG_TMPL_FOLDER="${REPO_SRC}/scripts/config_template/nginx" | |||||
NGINX_CONFIG_DEPLOY_FOLDER="${REPO_SRC}/config/nginx" | |||||
NGINX_CONF_PUBLIC="${REPO_NAME}.public.conf" | |||||
NGINX_CONF_PRIVATE="${REPO_NAME}.private.conf" | |||||
NGINX_CONF_PUBLIC_ADDR="${NGINX_CONFIG_DEPLOY_FOLDER}/${NGINX_CONF_PUBLIC}" | |||||
NGINX_CONF_PRIVATE_ADDR="${NGINX_CONFIG_DEPLOY_FOLDER}/${NGINX_CONF_PRIVATE}" | |||||
if [ "${PUBLIC_UPSTREAM_PORT}" != "" ]; then | |||||
UPSTREAM_ADDR_PUBLIC="127.0.0.1:${PUBLIC_UPSTREAM_PORT}" | |||||
fi | |||||
if [ "${PRIVATE_UPSTREAM_PORT}" != "" ]; then | |||||
UPSTREAM_ADDR_PRIVATE="127.0.0.1:${PRIVATE_UPSTREAM_PORT}" | |||||
fi | |||||
# systemctl | |||||
SYSTEMCTL_CONFIG_TMPL_FOLDER="${REPO_SRC}/scripts/config_template/systemctl" | |||||
SYSTEMCTL_CONFIG_DEPLOY_FOLDER="${REPO_SRC}/config/systemctl" | |||||
SYSTEMCTL_CONF="${REPO_NAME}.service" | |||||
SYSTEMCTL_CONF_ADDR="${SYSTEMCTL_CONFIG_DEPLOY_FOLDER}/${SYSTEMCTL_CONF}" | |||||
# release env | |||||
if [ "$RELEASE_ENV" == "dev" ]; then | |||||
RELEASE_ENV_LOCATION="$RELEASE_ENV" | |||||
elif [ "$RELEASE_ENV" == "beta" ]; then | |||||
RELEASE_ENV_LOCATION="$RELEASE_ENV" | |||||
elif [ "$RELEASE_ENV" == "online" ]; then | |||||
RELEASE_ENV_LOCATION="$RELEASE_ENV" | |||||
else | |||||
RELEASE_ENV_LOCATION="" | |||||
fi | |||||
if [ "$RELEASE_ENV_LOCATION" == "" ]; then | |||||
echo "please input an avaliable deploy environment [dev/beta/online]"; | |||||
echo "example: ./init_config.sh.sh beta"; | |||||
exit 1; | |||||
fi | |||||
# ------------------------------------------------------------------------------ | |||||
# scripts start | |||||
# check env | |||||
NOW_PWD=`pwd` | |||||
if [ "$NOW_PWD" != "${REPO_SRC}/scripts" ] && [ "$NOW_PWD" != "${REPO_SRC}" ]; then | |||||
echo -e "\033[43m[WARRING!] PWD is ${NOW_PWD}, but REPO_SRC is ${REPO_SRC} \033[0m"; | |||||
echo -e "please check your REPO_SRC config to make sure that you config this file correctly."; | |||||
exit 1; | |||||
fi | |||||
# [init nginx config] | |||||
# deploy tmpl config to deploy folder | |||||
# for public config | |||||
if [ "${PUBLIC_UPSTREAM_PORT}" != "" ]; then | |||||
# deploy tmpl config to deploy folder | |||||
if [ -f "${NGINX_CONF_PUBLIC_ADDR}" ]; then | |||||
rm -f "${NGINX_CONF_PUBLIC_ADDR}"; | |||||
fi | |||||
cp "${NGINX_CONFIG_TMPL_FOLDER}/${NGINX_CONF_TMPL_PUBLIC}" "${NGINX_CONF_PUBLIC_ADDR}"; | |||||
# replace config param | |||||
sed -i "s/REPO_NAME/${REPO_NAME}/g" "${NGINX_CONF_PUBLIC_ADDR}"; | |||||
# replace domain name | |||||
sed -i "s/DOMAIN_NAME/${DOMAIN_NAME}/g" "${NGINX_CONF_PUBLIC_ADDR}"; | |||||
# replace upstream addr | |||||
sed -i "s/UPSTREAM_ADDR/${UPSTREAM_ADDR_PUBLIC}/g" "${NGINX_CONF_PUBLIC_ADDR}"; | |||||
fi | |||||
# for private config | |||||
if [ "${PRIVATE_UPSTREAM_PORT}" != "" ]; then | |||||
# deploy tmpl config to deploy folder | |||||
if [ -f "${NGINX_CONF_PRIVATE_ADDR}" ]; then | |||||
rm -f "${NGINX_CONF_PRIVATE_ADDR}"; | |||||
fi | |||||
cp "${NGINX_CONFIG_TMPL_FOLDER}/${NGINX_CONF_TMPL_PRIVATE}" "${NGINX_CONF_PRIVATE_ADDR}" | |||||
# replace config param | |||||
sed -i "s/REPO_NAME/${REPO_NAME}/g" "${NGINX_CONF_PRIVATE_ADDR}"; | |||||
# replace domain name | |||||
sed -i "s/DOMAIN_NAME/${DOMAIN_NAME}/g" "${NGINX_CONF_PRIVATE_ADDR}"; | |||||
# replace upstream addr | |||||
sed -i "s/UPSTREAM_ADDR/${UPSTREAM_ADDR_PRIVATE}/g" "${NGINX_CONF_PRIVATE_ADDR}"; | |||||
fi | |||||
# [init systemctl config] | |||||
# deploy tmpl config to deploy folder | |||||
# for beta service | |||||
if [ "${RELEASE_ENV_LOCATION}" == "beta" ]; then | |||||
if [ -f "${SYSTEMCTL_CONF_ADDR}" ]; then | |||||
rm -f "${SYSTEMCTL_CONF_ADDR}"; | |||||
fi | |||||
cp "${SYSTEMCTL_CONFIG_TMPL_FOLDER}/${SYSTEMCTL_CONF_TMPL_BETA}" "${SYSTEMCTL_CONF_ADDR}" | |||||
# replace repo name | |||||
sed -i "s/REPO_NAME/${REPO_NAME}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||||
# replace build target | |||||
sed -i "s/BUILD_TARGET/${BUILD_TARGET}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||||
fi | |||||
# for online service | |||||
if [ "${RELEASE_ENV_LOCATION}" == "online" ]; then | |||||
if [ -f "${SYSTEMCTL_CONF_ADDR}" ]; then | |||||
rm -f "${SYSTEMCTL_CONF_ADDR}"; | |||||
fi | |||||
cp "${SYSTEMCTL_CONFIG_TMPL_FOLDER}/${SYSTEMCTL_CONF_TMPL_RELEASE}" "${SYSTEMCTL_CONF_ADDR}" | |||||
# replace repo name | |||||
sed -i "s/REPO_NAME/${REPO_NAME}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||||
# replace build target | |||||
sed -i "s/BUILD_TARGET/${BUILD_TARGET}/g" "${SYSTEMCTL_CONF_ADDR}"; | |||||
fi | |||||
exit 0; |
@ -0,0 +1,11 @@ | |||||
package base | |||||
import ( | |||||
"github.com/astaxie/beego" | |||||
) | |||||
const configFilePath = "/data/repo/baidu_link_submit_ms/src/config/app.conf" | |||||
func init() { | |||||
beego.LoadAppConfig("ini", configFilePath) | |||||
} |
@ -0,0 +1,21 @@ | |||||
appname = hi_guoqian_go_ms | |||||
httpport = 13100 | |||||
runmode = dev | |||||
autorender = false | |||||
copyrequestbody = true | |||||
EnableDocs = false | |||||
[dev] | |||||
redisAddress = 192.168.0.204:6379 | |||||
redisDb = 0 | |||||
redisPassword= | |||||
[beta] | |||||
redisAddress = 192.168.0.204:6379 | |||||
redisDb = 0 | |||||
redisPassword= | |||||
[proc] | |||||
redisAddress = 192.168.100.15:6379 | |||||
redisDb = 1 | |||||
redisPassword=rcASeLT1NayQp59B4UiM |
@ -0,0 +1,59 @@ | |||||
package controllers | |||||
import ( | |||||
. "errors" | |||||
"github.com/astaxie/beego" | |||||
. "middlewares" | |||||
. "models" | |||||
) | |||||
var ( | |||||
baseUrl string = "https://juejin.im" | |||||
typePathMap map[string]string = map[string]string{ | |||||
"link": "/entry/", | |||||
"column": "/post/", | |||||
} | |||||
) | |||||
type EventController struct { | |||||
beego.Controller | |||||
} | |||||
//start | |||||
func (this *EventController) Contribution() { | |||||
ret, err := IncrRedis("hi:guoqian") | |||||
controller := &BeegoController{Controller: this.Controller} | |||||
if err != nil { | |||||
if err.Error() == M_NO_RESULT { | |||||
controller.RenderOutput(EmptyErr(nil)) | |||||
return | |||||
} else { | |||||
controller.RenderOutput(ServerErr(err.Error())) | |||||
return | |||||
} | |||||
}else{ | |||||
controller.RenderOutput(Success(ret)) | |||||
return | |||||
} | |||||
} | |||||
func (this *EventController) Second() { | |||||
ret, err := GetRedis("hi:guoqian") | |||||
controller := &BeegoController{Controller: this.Controller} | |||||
if err != nil { | |||||
if err.Error() == M_NO_RESULT { | |||||
controller.RenderOutput(EmptyErr(nil)) | |||||
return | |||||
} else { | |||||
controller.RenderOutput(ServerErr(err.Error())) | |||||
return | |||||
} | |||||
}else{ | |||||
controller.RenderOutput(Success(ret)) | |||||
return | |||||
} | |||||
} | |||||
//end |
@ -0,0 +1,25 @@ | |||||
package main | |||||
import ( | |||||
"github.com/astaxie/beego" | |||||
_ "base" | |||||
_ "models" | |||||
_ "routers" | |||||
) | |||||
func main() { | |||||
initLog() | |||||
beego.Run() | |||||
} | |||||
func initLog() { | |||||
name := beego.AppConfig.String("appname") | |||||
logFilePath := "/data/repo/" + name + "/logs/" + name + ".log" | |||||
beego.SetLogger("file", `{"filename":"` + logFilePath + `","level":2,"daily":true,"maxdays":10}`) | |||||
if beego.AppConfig.String("runmode") != "dev" { | |||||
beego.BeeLogger.DelLogger("console") | |||||
} | |||||
beego.BeeLogger.EnableFuncCallDepth(true) | |||||
beego.SetLogFuncCall(true) | |||||
beego.BeeLogger.Async() | |||||
} |
@ -0,0 +1,39 @@ | |||||
package middleware | |||||
import ( | |||||
"github.com/astaxie/beego" | |||||
) | |||||
type BeegoController struct { | |||||
Controller beego.Controller | |||||
} | |||||
func (c *BeegoController) GetQuery(key string) string { | |||||
return c.Controller.Input().Get(key) | |||||
} | |||||
func (c *BeegoController) GetForm(key string) string { | |||||
return c.Controller.Input().Get(key) | |||||
} | |||||
func (c *BeegoController) GetHeader(key string) string { | |||||
return c.Controller.Ctx.Input.Header(key) | |||||
} | |||||
func (c *BeegoController) GetCookie(key string) string { | |||||
return c.Controller.Ctx.Input.Cookie(key) | |||||
} | |||||
func (c *BeegoController) GetBody() []byte { | |||||
return c.Controller.Ctx.Input.RequestBody | |||||
} | |||||
func (c *BeegoController) GetPath(key string) string { | |||||
return c.Controller.GetString(":" + key) | |||||
} | |||||
func (c *BeegoController) GetArray(key string) []string { | |||||
array := make([]string, 0) | |||||
c.Controller.Ctx.Input.Bind(&array, key) | |||||
return array | |||||
} | |||||
func (c *BeegoController) RenderOutput(ret *RenderStruct) { | |||||
c.Controller.Ctx.Output.Status = ret.Status | |||||
c.Controller.Data["json"] = ret | |||||
c.Controller.ServeJSON() | |||||
} |
@ -0,0 +1,306 @@ | |||||
package middleware | |||||
import ( | |||||
"encoding/json" | |||||
"strconv" | |||||
"time" | |||||
) | |||||
const ( | |||||
TYPE_STRING = iota | |||||
TYPE_INT | |||||
TYPE_FLOAT | |||||
TYPE_BOOLEAN | |||||
TYPE_TIME | |||||
TYPE_ARRAY | |||||
TYPE_JSON_OBJECT | |||||
) | |||||
const ( | |||||
POS_QUERY = iota | |||||
POS_HEADER | |||||
POS_BODY_FORM | |||||
POS_BODY_JSON | |||||
POS_PATH | |||||
POS_COOKIE | |||||
) | |||||
const ( | |||||
TIME_LAYOUT = "2006-01-02T15:04:05Z" | |||||
) | |||||
type InputInterface interface { | |||||
GetQuery(key string) string | |||||
GetForm(key string) string | |||||
GetHeader(key string) string | |||||
GetCookie(key string) string | |||||
GetBody() []byte | |||||
GetPath(key string) string | |||||
GetArray(key string) []string | |||||
RenderOutput(r *RenderStruct) | |||||
} | |||||
type InputContainer struct { | |||||
simpleMap map[string]interface{} | |||||
objectMap map[string][]byte | |||||
arrayMap map[string][]string | |||||
} | |||||
type InputRule struct { | |||||
Name string | |||||
Description string | |||||
Position int | |||||
Type int | |||||
//此处有蹊跷 | |||||
Limit []string | |||||
Necessary bool | |||||
Max int | |||||
Min int | |||||
Default interface{} | |||||
} | |||||
type CheckError struct { | |||||
Missing string `json:"missing" xml:"missing"` | |||||
Illegal string `json:"illegal" xml:"illegal"` | |||||
} | |||||
func (c *CheckError) Error() string { | |||||
return "input error" | |||||
} | |||||
//must use this func to create a new container | |||||
func NewContainer() *InputContainer { | |||||
return &InputContainer{ | |||||
simpleMap: make(map[string]interface{}), | |||||
objectMap: make(map[string][]byte), | |||||
arrayMap: make(map[string][]string), | |||||
} | |||||
} | |||||
func (i *InputContainer) CheckInput(input InputInterface, rules []*InputRule) *CheckError { | |||||
for _, rule := range rules { | |||||
//check special input type | |||||
switch rule.Type { | |||||
case TYPE_ARRAY: | |||||
arr := input.GetArray(rule.Name) | |||||
if rule.Necessary && len(arr) <= 0 { | |||||
return &CheckError{ | |||||
Missing: rule.Name, | |||||
} | |||||
} | |||||
if rule.Max > 0 { | |||||
if len(arr) > rule.Max { | |||||
return &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
if rule.Min > 0 { | |||||
if len(arr) < rule.Min { | |||||
return &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
i.arrayMap[rule.Name] = arr | |||||
case TYPE_JSON_OBJECT: | |||||
var bytes []byte | |||||
switch rule.Position { | |||||
default: | |||||
fallthrough | |||||
case POS_BODY_JSON: | |||||
bytes = input.GetBody() | |||||
case POS_QUERY: | |||||
bytes = []byte(input.GetQuery(rule.Name)) | |||||
case POS_BODY_FORM: | |||||
bytes = []byte(input.GetForm(rule.Name)) | |||||
case POS_HEADER: | |||||
bytes = []byte(input.GetHeader(rule.Name)) | |||||
case POS_COOKIE: | |||||
bytes = []byte(input.GetCookie(rule.Name)) | |||||
} | |||||
if rule.Necessary && len(bytes) <= 0 { | |||||
return &CheckError{ | |||||
Missing: rule.Name, | |||||
} | |||||
} else if len(bytes) <= 0 { | |||||
continue | |||||
} | |||||
err := json.Unmarshal(bytes, &map[string]interface{}{}) | |||||
if err != nil { | |||||
return &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
i.objectMap[rule.Name] = bytes | |||||
default: | |||||
//check normal input type | |||||
var val string | |||||
switch rule.Position { | |||||
case POS_PATH: | |||||
val = input.GetPath(rule.Name) | |||||
default: | |||||
fallthrough | |||||
case POS_QUERY: | |||||
val = input.GetQuery(rule.Name) | |||||
case POS_BODY_FORM: | |||||
val = input.GetForm(rule.Name) | |||||
case POS_HEADER: | |||||
val = input.GetHeader(rule.Name) | |||||
case POS_COOKIE: | |||||
val = input.GetCookie(rule.Name) | |||||
} | |||||
if rule.Necessary && len(val) <= 0 { | |||||
return &CheckError{ | |||||
Missing: rule.Name, | |||||
} | |||||
} else if len(val) <= 0 { | |||||
i.simpleMap[rule.Name] = rule.Default | |||||
} else { | |||||
res, err := checkValue(rule, val) | |||||
if err != nil { | |||||
return err | |||||
} | |||||
i.simpleMap[rule.Name] = res | |||||
} | |||||
} | |||||
} | |||||
return nil | |||||
} | |||||
func checkValue(rule *InputRule, val string) (interface{}, *CheckError) { | |||||
limit := len(rule.Limit) <= 0 | |||||
if !limit { | |||||
for _, i := range rule.Limit { | |||||
if val == i { | |||||
limit = true | |||||
break | |||||
} | |||||
} | |||||
if !limit { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
switch rule.Type { | |||||
default: | |||||
fallthrough | |||||
case TYPE_STRING: | |||||
if rule.Max > 0 { | |||||
if len(val) > rule.Max { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
if rule.Min > 0 { | |||||
if len(val) < rule.Min { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
return val, nil | |||||
case TYPE_INT: | |||||
intVal, err := strconv.Atoi(val) | |||||
if err != nil { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
if rule.Max > 0 { | |||||
if intVal > rule.Max { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
if rule.Min > 0 { | |||||
if intVal < rule.Min { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
return intVal, nil | |||||
case TYPE_FLOAT: | |||||
floatVal, err := strconv.ParseFloat(val, 64) | |||||
if err != nil { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
if rule.Max > 0 { | |||||
if floatVal > float64(rule.Max) { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
if rule.Min > 0 { | |||||
if floatVal < float64(rule.Min) { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
} | |||||
return floatVal, nil | |||||
case TYPE_BOOLEAN: | |||||
booleanVal, err := strconv.ParseBool(val) | |||||
if err != nil { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
return booleanVal, nil | |||||
case TYPE_TIME: | |||||
t, err := time.Parse(TIME_LAYOUT, val) | |||||
if err != nil { | |||||
return nil, &CheckError{ | |||||
Illegal: rule.Name, | |||||
} | |||||
} | |||||
return t, nil | |||||
} | |||||
} | |||||
func (i *InputContainer) GetInt(key string) int { | |||||
if res, ok := i.simpleMap[key].(int); ok { | |||||
return res | |||||
} | |||||
return 0 | |||||
} | |||||
func (i *InputContainer) GetBoolean(key string) bool { | |||||
if res, ok := i.simpleMap[key].(bool); ok { | |||||
return res | |||||
} | |||||
return false | |||||
} | |||||
func (i *InputContainer) GetFloat(key string) float64 { | |||||
if res, ok := i.simpleMap[key].(float64); ok { | |||||
return res | |||||
} | |||||
return 0 | |||||
} | |||||
func (i *InputContainer) GetString(key string) string { | |||||
if res, ok := i.simpleMap[key].(string); ok { | |||||
return res | |||||
} | |||||
return "" | |||||
} | |||||
func (i *InputContainer) GetArray(key string) []string { | |||||
return i.arrayMap[key] | |||||
} | |||||
func (i *InputContainer) GetObject(key string, obj interface{}) error { | |||||
bytes := i.objectMap[key] | |||||
return json.Unmarshal(bytes, obj) | |||||
} | |||||
func (i *InputContainer) GetTime(key string) time.Time { | |||||
if res, ok := i.simpleMap[key].(time.Time); ok { | |||||
return res | |||||
} | |||||
return time.Time{} | |||||
} |
@ -0,0 +1,112 @@ | |||||
package middleware | |||||
import ( | |||||
"github.com/astaxie/beego" | |||||
"net/http" | |||||
) | |||||
const ( | |||||
S_UNKNOWN_ERROR = iota | |||||
S_OK | |||||
S_NO_RESULT | |||||
S_ILLEGAL_TOKEN | |||||
S_WRONG_INPUT | |||||
S_WRONG_EXEC_RESULT | |||||
S_TOKEN_EXPIRE | |||||
) | |||||
const ( | |||||
M_OK = "success" | |||||
M_NO_RESULT = "no result" | |||||
M_ILLEGAL_TOKEN = "illegal token" | |||||
M_TOKEN_EXPIRE = "token expired" | |||||
M_ILLEGAL_SESSION = "illegal session" | |||||
M_WRONG_INPUT = "wrong input" | |||||
M_WRONG_EXEC_RESULT = "exec error" | |||||
) | |||||
type RenderStruct struct { | |||||
Status int `json:"-"` | |||||
S int `json:"s"` | |||||
M string `json:"m"` | |||||
D interface{} `json:"d"` | |||||
} | |||||
func Success(list interface{}) (r *RenderStruct) { | |||||
r = new(RenderStruct) | |||||
r.Status = http.StatusOK | |||||
r.S = S_OK | |||||
r.M = M_OK | |||||
if list == nil { | |||||
list = []interface{}{} | |||||
} | |||||
r.D = list | |||||
return | |||||
} | |||||
func EmptyErr(list interface{}) (r *RenderStruct) { | |||||
r = new(RenderStruct) | |||||
r.Status = http.StatusOK | |||||
r.S = S_NO_RESULT | |||||
r.M = M_NO_RESULT | |||||
if list == nil { | |||||
list = []interface{}{} | |||||
} | |||||
r.D = list | |||||
return | |||||
} | |||||
func InputErr(data interface{}) (r *RenderStruct) { | |||||
r = new(RenderStruct) | |||||
r.Status = http.StatusBadRequest | |||||
if data == nil { | |||||
data = []interface{}{} | |||||
} | |||||
r.S = S_WRONG_INPUT | |||||
r.M = M_WRONG_INPUT | |||||
r.D = data | |||||
if beego.BConfig.RunMode != "dev" { | |||||
r.D = []interface{}{} | |||||
} | |||||
return | |||||
} | |||||
func NormalErr(status int, s int, msg string, d interface{}) (r *RenderStruct) { | |||||
r = new(RenderStruct) | |||||
r.Status = status | |||||
r.S = s | |||||
r.M = msg | |||||
if d == nil { | |||||
d = []interface{}{} | |||||
} | |||||
r.D = d | |||||
return | |||||
} | |||||
func ServerErr(message string) (r *RenderStruct) { | |||||
r = new(RenderStruct) | |||||
r.Status = http.StatusInternalServerError | |||||
r.S = S_WRONG_EXEC_RESULT | |||||
r.M = message | |||||
if len(message) <= 0 { | |||||
r.M = M_WRONG_EXEC_RESULT | |||||
} | |||||
r.D = []interface{}{} | |||||
return | |||||
} | |||||
func TokenErr(errorType int) (r *RenderStruct) { | |||||
r = new(RenderStruct) | |||||
r.Status = http.StatusForbidden | |||||
switch errorType { | |||||
case S_TOKEN_EXPIRE: | |||||
r.S = S_TOKEN_EXPIRE | |||||
r.M = M_TOKEN_EXPIRE | |||||
default: | |||||
fallthrough | |||||
case S_ILLEGAL_TOKEN: | |||||
r.S = S_ILLEGAL_TOKEN | |||||
r.M = M_ILLEGAL_TOKEN | |||||
} | |||||
r.D = []interface{}{} | |||||
return | |||||
} |
@ -0,0 +1,65 @@ | |||||
package models | |||||
import ( | |||||
"github.com/astaxie/beego" | |||||
"github.com/garyburd/redigo/redis" | |||||
"time" | |||||
) | |||||
var RedisPool *redis.Pool | |||||
func init() { | |||||
address := beego.AppConfig.String("redisAddress") | |||||
password := beego.AppConfig.String("redisPassword") | |||||
dbNum := beego.AppConfig.String("redisDb") | |||||
dialFunc := func() (c redis.Conn, err error) { | |||||
// c, err = redis.Dial("tcp", address) | |||||
// func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) | |||||
c, err = redis.DialTimeout("tcp", address, 3*time.Second, 3*time.Second, 3*time.Second) | |||||
if err != nil { | |||||
return nil, err | |||||
} | |||||
if beego.AppConfig.String("redisPassword") != "" { | |||||
if _, err := c.Do("AUTH", password); err != nil { | |||||
c.Close() | |||||
return nil, err | |||||
} | |||||
} | |||||
_, selecterr := c.Do("SELECT", dbNum) | |||||
if selecterr != nil { | |||||
c.Close() | |||||
return nil, selecterr | |||||
} | |||||
return | |||||
} | |||||
// initialize a new pool | |||||
RedisPool = &redis.Pool{ | |||||
MaxIdle: 100, | |||||
MaxActive: 50, | |||||
IdleTimeout: 180 * time.Second, | |||||
Dial: dialFunc, | |||||
} | |||||
} | |||||
func SetRedis(key string, value []byte) error { | |||||
conn := RedisPool.Get() | |||||
defer conn.Close() | |||||
conn.Send("SET", key, value) | |||||
return conn.Flush() | |||||
} | |||||
func GetRedis(key string) (int64, error) { | |||||
conn := RedisPool.Get() | |||||
defer conn.Close() | |||||
ret, err := redis.Int64(conn.Do("GET", key)) | |||||
return ret, err | |||||
} | |||||
func IncrRedis(key string) (int64, error) { | |||||
conn := RedisPool.Get() | |||||
defer conn.Close() | |||||
ret, err := redis.Int64(conn.Do("INCR", key)) | |||||
return ret, err | |||||
} |
@ -0,0 +1,19 @@ | |||||
package routers | |||||
import ( | |||||
"net/http" | |||||
"github.com/astaxie/beego" | |||||
. "controllers" | |||||
) | |||||
func init() { | |||||
eventController := EventController{} | |||||
namespace := beego.NewNamespace("/v1", | |||||
beego.NSRouter("/second", &eventController, "get:Second"), | |||||
beego.NSRouter("/contribution", &eventController, "post:Contribution"), | |||||
) | |||||
beego.AddNamespace(namespace) | |||||
beego.ErrorHandler("404", func(w http.ResponseWriter, r *http.Request) { | |||||
w.WriteHeader(http.StatusNotFound) | |||||
}) | |||||
} |