Authored by zhouxiang

Merge branch 'switch'

... ... @@ -124,6 +124,11 @@
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
</dependency>
<dependency>
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
... ...
package com.monitor.common.util;
import com.github.jknack.handlebars.Handlebars;
import com.github.jknack.handlebars.Template;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Map;
/**
* Created by zhouxiang on 2016/10/20.
*/
public class HandlebarsUtils {
private static Handlebars handlebars = new Handlebars();
static {
handlebars.setStartDelimiter("{@{");
handlebars.setEndDelimiter("}@}");
}
public static String replace(Map<String, Object> obj,String tempfilePath,String createFileName) {
String result = "";
try {
Template template = handlebars.compile(tempfilePath);
Writer writer = new FileWriter(createFileName);
template.apply(obj,writer);
writer.flush();
writer.close();
return template.apply(obj);
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public static void main(String[] args) {
}
}
... ...
user www www;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
pid logs/nginx.pid;
# [ debug | info | notice | warn | error | crit ]
#error_log /Data/logs/nginx/nginx_error.log info;
error_log /Data/logs/nginx/nginx_error.log info;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;
events
{
use epoll;
#maxclient = worker_processes * worker_connections / cpu_number
worker_connections 51200;
}
http
{
include mime.types;
default_type application/octet-stream;
#charset gb2312,utf-8;
charset utf-8;
log_format fenxi '$remote_addr|$http_x_forwarded_for|[$time_local]|$http_host|$request|'
'$status|$body_bytes_sent|$request_time|$upstream_response_time|$upstream_cache_status|$http_referer|'
'$http_user_agent|$upstream_addr';
#General Options
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_body_buffer_size 8m; #256k
#
#server_tokens off;
ignore_invalid_headers on;
recursive_error_pages on;
server_name_in_redirect off;
sendfile on;
#timeouts
keepalive_timeout 60;
#test
#client_body_timeout 3m;
#client_header_timeout 3m;
#send_timeout 3m;
#TCP Options
tcp_nopush on;
tcp_nodelay on;
#fastcgi options
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#set_real_ip_from 10.159.191.0/24;
#real_ip_header X-Forwarded-For;
#hiden php version
fastcgi_hide_header X-Powered-By;
#size limits
client_max_body_size 50m;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
#gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml application/json;
gzip_vary on;
fastcgi_temp_path /dev/shm/fastcgi_temp;
client_body_temp_path /dev/shm/client_body_temp;
# where the lua package exists
lua_package_path "/Data/local/openresty-1.9.15.1/nginx/conf/lua/?.lua;;";
init_by_lua_file "conf/lua/init_lua.lua";
#upstream web
upstream oldservice {
server service.api.yohobuy.com ;
}
upstream oldapi {
server api.open.yohobuy.com ;
}
#brower service
upstream brower {
server 172.31.30.165:8092;
server 172.31.57.222:8092;
server 172.31.57.221:8092;
}
upstream social {
server 172.31.30.165:8095;
server 172.31.30.165:8095;
}
upstream apigateway {
{@{#each ips}@}server {@{this}@}:8080 max_fails=5 fail_timeout=3s;
{@{/each}@}
keepalive 32;
}
upstream grayapigateway {
{@{#each grayips}@}server {@{this}@}:8080 max_fails=5 fail_timeout=3s;
{@{/each}@}
keepalive 32;
}
upstream pay.yohobuy.com {
server 172.31.55.207 max_fails=5 fail_timeout=3s weight=10;
server 172.31.56.135 max_fails=5 fail_timeout=3s weight=50;
}
upstream www.yohobuy.com {
server www.yohobuy.com;
}
upstream union {
server 172.31.16.99:8088;
}
upstream activityApi{
server 172.31.16.98:8090;
}
upstream apiWechat {
server 172.31.31.13:8094 ;
}
#upstream
fastcgi_next_upstream error timeout invalid_header http_500;
#limit_zone limit $binary_remote_addr 1m;
#fastcgi cache
#fastcgi_cache_path /nginxcache levels=1:2 keys_zone=two:10m inactive=1d max_size=3000m;
#for example just for study! have fun!
include vhosts/api.yoho.cn.conf;
include vhosts/mapi.yohobuy.com.conf;
include vhosts/pay.yohobuy.com.conf;
include vhosts/service.yoho.cn.conf;
include vhosts/api_single.yoho.cn.conf;
include vhosts/unknown.conf;
}
... ...
local resolver=require "resty.dns.resolver"
local cjson=require "cjson"
local aes=require "resty.aes"
ngx.lookup_context={}
local context=ngx.lookup_context
context.dns_server={"114.114.114.114"}
-- 1:aws ,2:qq ,3:aws+qq
context.cloud_flag={@{flag}@}
--add 20160823 notLogin=aws/tencent
context.strategy_param={["model"]=1024,["tencentMax"]=128,["notLogin"]="aws"}
context.tencent_ips={
["api.yoho.cn"]={{ip="123.206.1.98",ttl=60},{ip="123.206.2.80",ttl=60}},
["service.yoho.cn"]={{ip="123.206.1.98",ttl=60},{ip="123.206.2.80",ttl=60}}
-- ["m.yohobuy.com"]={{ip="123.206.1.105",ttl=60}}
}
context.tencent_ips_encrypt={
}
-- aws domain slb domain
context.aws_domains={
["api.yoho.cn"]="app-java-168863769.cn-north-1.elb.amazonaws.com.cn",
["service.yoho.cn"]="service-yoho-579825100.cn-north-1.elb.amazonaws.com.cn"
-- ["m.yohobuy.com"]="pch5-1209971887.cn-north-1.elb.amazonaws.com.cn"
}
--add 20160823 use for strategy
context.aws_ips={}
context.aws_ips_encrypt={
}
context.init_flag={
}
context.encrypt_param={
secret_key="yoho9646YOHO9646",
iv="YOHO9646yoho9646"
}
context.encrypt=function(msg)
if not msg then
return
end
local aes_128_cbc_pkcs7padding = assert(aes:new(context.encrypt_param.secret_key,nil,aes.cipher(128,"cbc"),{iv=context.encrypt_param.iv}))
local encrypt_msg=aes_128_cbc_pkcs7padding:encrypt(msg)
return ngx.encode_base64(encrypt_msg)
end
context.encrypt_ips=function(ips)
local ips_json=cjson.encode(ips)
local md5=ngx.md5(ips_json)
local resp_content={content=ips_json,md5=md5}
local resp_json=cjson.encode(resp_content)
local ips_encrypt=context.encrypt(resp_json)
return ips_encrypt
end
local acquire_ip
acquire_ip=function(args)
-- define a function for acquire dns's ip return type is {ips={{ip="100.100.100.100",ttl=100},{ip="100.100.100.100",ttl=100}},delay_in_second=60}
context.resolve_domain_to_ip=function(domain)
if not domain then
return nil
end
local r,err=resolver:new{
nameservers=context.dns_server
}
if not r then
ngx.log(ngx.ERR,"resolve domain error:",err)
return nil
end
local answers,err=r:tcp_query(domain)
if (not answers) or (#answers <=0) then
ngx.log(ngx.ERR,"resolve domain tcp query error:",err)
return nil
end
local ips_and_delay_second={ips={}}
local delay_in_second=30
for i,ans in ipairs(answers) do
if ans.address and ans.ttl then
delay_in_second=30>ans.ttl and ans.ttl or 30
local ip={ip=ans.address,ttl=delay_in_second}
table.insert(ips_and_delay_second.ips,ip)
end
end
ips_and_delay_second.delay_in_second=delay_in_second
ngx.log(ngx.INFO,domain .. " ips:",cjson.encode(ips_and_delay_second))
return ips_and_delay_second
end
local resolver_dns
resolver_dns=function(domain)
if not domain then
return
end
local org_domain=domain
local domain=context.aws_domains[domain]
if not domain then
return
end
-- first time init the ip tables must success
local aws_ips_temp
while not context.init_flag[domain] do
aws_ips_temp=context.resolve_domain_to_ip(domain)
if aws_ips_temp and #(aws_ips_temp.ips)>0 then
-- add 20160823
context.aws_ips[org_domain]= aws_ips_temp.ips;
local encrypt_ips=context.encrypt_ips(aws_ips_temp.ips)
context.aws_ips_encrypt[org_domain]=encrypt_ips
context.init_flag[domain]=true
end
end
local aws_ips_temp = context.resolve_domain_to_ip(domain)
if aws_ips_temp and #(aws_ips_temp.ips)>0 then
-- add 20160823
context.aws_ips[org_domain]= aws_ips_temp.ips;
local encrypt_ips=context.encrypt_ips(aws_ips_temp.ips)
ngx.log(ngx.INFO,org_domain .. " encrypt ips is " .. encrypt_ips)
context.aws_ips_encrypt[org_domain]=encrypt_ips
end
end
local timer_resolver_dns
timer_resolver_dns=function(premature,domain)
pcall(resolver_dns,domain)
ngx.timer.at(10,timer_resolver_dns,domain)
end
-- init tencent ips encrypt list
for k,v in pairs(context.tencent_ips) do
context.tencent_ips_encrypt[k]=context.encrypt_ips(v)
end
-- aws task execute
for k,v in pairs(context.aws_domains) do
timer_resolver_dns(false,k)
end
end
-- first time execute right now
ngx.timer.at(0,acquire_ip)
... ...
-- init redis twemproxy config
local redis_config1={host="127.0.0.1",port="6379",auth=nil,timeout=2000,max_idle_timeout=60000,pool_size=1000}
local redis_util=require("redisutil")
local redis1=redis_util:new(redis_config1)
lua_context={}
lua_context["redises"]={redis1}
open_limit_flow={@{open_limit_flow}@}
api_default_max_per_sencond=1000
service_default_max_per_sencond=1000
default_err_code=9999991
default_err_msg="系统正忙,请稍后重试!"
--limit interface
limit_config={
{@{#each limit_config}@}{@{{this}}@}
{@{/each}@}
}
limit_service_config={
{@{#each limit_service_config}@}{@{{this}}@}
{@{/each}@}
}
... ...
local cjson = require "cjson"
local aes = require "resty.aes"
local upt = require "url_process_tool"
local icutil = require "iconfig_util"
--5b2d8b4b242e067616c6cd98851b2306 close
--2a90dfa0f37b92aaebf369e9a4d38ba4 open
local open_dl = "{@{open_dl}@}"
local close_dl = "5b2d8b4b242e067616c6cd98851b2306"
local function common_lb ()
local response_table = {
code = 200,
ae = "e0323a9039add2978bf5b49550572c7c",
url = "http://m.yohobuy.com",
tl = "352f028bd6ecf28de1c285c573642659",
rp = "17d7a40f313560d4d9a1189a91e45ab9",
dl = open_dl,
dli = open_dl,
dlwi = open_dl
}
return response_table
end
function lb()
ngx.log (ngx.INFO, "----- lb START ----- ")
-- args error --
local args = ngx.var.args
if not args then
icutil.error_response ("40011","args not found")
ngx.log (ngx.ERROR, "- 40011 - args : ", args, "---")
return
end
local url_args = upt.url_args_decrypt(args)
if not url_args then
icutil.error_response ("40012","args not found")
ngx.log (ngx.ERROR, "- 40012 - args : ", args, "---")
return
end
-- args parse --
ngx.req.set_uri_args(url_args)
local uri_args = ngx.req.get_uri_args()
--for k,v in pairs(uri_args) do ngx.log(ngx.INFO," k = ", k, " v = ", v) end
local uid = uri_args["uid"]
local app_ver = uri_args["app_ver"]
local os = uri_args["os"]
local udid = uri_args["udid"]
local osversion = uri_args["osv"]
ngx.log (ngx.INFO, "5、--- uid : ", uid, " app_ver :", app_ver, " os :", os, "---")
local result
-- ios
local ios_lb = {
["4.8.1"] = function()
return common_lb()
end,
["4.9.2"] = function()
local response_table = common_lb()
response_table.dli = "2a90dfa0f37b92aaebf369e9a4d38ba4"
return response_table
end
,
["5.0.0"] = function()
local response_table = common_lb()
if osversion == "7" then
response_table.dli = close_dl
else
response_table.dli = open_dl
end
return response_table
end
}
-- anopen_stringdroid
local android_lb = {
["4.8.1"] = function()
return common_lb()
end,
["5.0.0"] = function()
local response_table = common_lb()
local dla_value = { dlw = open_dl, dlp = close_dl }
response_table.dla = dla_value
return response_table
end
}
-- switch 0:ios 1:android
if os == "0" then
ngx.log (ngx.INFO, "----- 1. enter ios lb ----- ")
if ios_lb[app_ver] ~= nil and ios_lb[app_ver]() ~= nil then
result = ios_lb[app_ver]()
ngx.log (ngx.INFO, "----- 2. app_ver found ----- ")
else
result = common_lb()
ngx.log (ngx.INFO, "----- 2. app_ver not found ----- ")
end
elseif os == "1" then
ngx.log (ngx.INFO, "----- enter android lb ----- ")
if android_lb[app_ver] ~= nil and android_lb[app_ver]() ~= nil then
result = android_lb[app_ver]()
ngx.log (ngx.INFO, "----- 2. app_ver found ----- ")
else
result = common_lb()
ngx.log (ngx.INFO, "----- 2. app_ver not found ----- ")
end
else
result = icutil.error_response ("40013","os error")
ngx.log (ngx.ERR, "- 40013 - enter error lb ----- ")
ngx.log (ngx.ERR, "- 40013 - uid : ", uid, " app_ver :", app_ver, " os :", os, "---")
end
--response
ngx.header["Content-type"]="text/plain;charset=utf-8"
local result_json = cjson.encode(result)
local resultstr = upt.url_args_encrypt (result_json)
ngx.log (ngx.INFO, string.format ("--- response %s ---",resultstr))
ngx.say(resultstr)
ngx.log (ngx.INFO, "----- lb OVER ----- ")
end
lb()
\ No newline at end of file
... ...
user www www;
worker_processes 8;
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
pid logs/nginx.pid;
# [ debug | info | notice | warn | error | crit ]
#error_log /Data/logs/nginx/nginx_error.log info;
error_log /Data/logs/nginx/nginx_error.log info;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;
events
{
use epoll;
#maxclient = worker_processes * worker_connections / cpu_number
worker_connections 51200;
}
http
{
include mime.types;
default_type application/octet-stream;
#charset gb2312,utf-8;
charset utf-8;
log_format fenxi '$remote_addr|$http_x_forwarded_for|[$time_local]|$http_host|$request|'
'$status|$body_bytes_sent|$request_time|$upstream_response_time|$upstream_cache_status|$http_referer|'
'$http_user_agent|$upstream_addr';
#General Options
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_body_buffer_size 8m; #256k
#
#server_tokens off;
ignore_invalid_headers on;
recursive_error_pages on;
server_name_in_redirect off;
sendfile on;
#timeouts
keepalive_timeout 60;
#test
#client_body_timeout 3m;
#client_header_timeout 3m;
#send_timeout 3m;
#TCP Options
tcp_nopush on;
tcp_nodelay on;
#fastcgi options
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#set_real_ip_from 10.159.191.0/24;
#real_ip_header X-Forwarded-For;
#hiden php version
fastcgi_hide_header X-Powered-By;
#size limits
client_max_body_size 50m;
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
#gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml application/json;
gzip_vary on;
fastcgi_temp_path /dev/shm/fastcgi_temp;
client_body_temp_path /dev/shm/client_body_temp;
# where the lua package exists
lua_package_path "/Data/local/openresty-1.9.15.1/nginx/conf/lua/?.lua;;";
init_by_lua_file "conf/lua/init_lua.lua";
#upstream web
upstream oldservice {
server service.api.yohobuy.com ;
}
upstream oldapi {
server api.open.yohobuy.com ;
}
#brower service
upstream brower {
server 10.66.0.6:8092;
}
#social service
upstream social {
server 10.66.0.44:8095;
server 10.66.0.229:8095;
}
upstream apigateway {
{@{#each ips}@}server {@{this}@}:8080 max_fails=5 fail_timeout=3s;
{@{/each}@}
keepalive 32;
}
upstream grayapigateway{
# ip_hash;
{@{#each grayips}@}server {@{this}@}:8080 max_fails=5 fail_timeout=3s;
{@{/each}@}
keepalive 32;
}
## order picture check
upstream yoho-dashboard {
server 172.31.25.5:8089;
}
upstream pay.yohobuy.com {
server 172.31.55.207 max_fails=5 fail_timeout=3s weight=10;
server 172.31.56.135 max_fails=5 fail_timeout=3s weight=50;
}
upstream www.yohobuy.com {
server www.yohobuy.com;
}
upstream union {
server 172.31.16.99:8088;
}
upstream activityApi{
server 10.66.0.16:8090;
}
upstream apiWechat {
server 172.31.31.13:8094 ;
}
#upstream
fastcgi_next_upstream error timeout invalid_header http_500;
#limit_zone limit $binary_remote_addr 1m;
#fastcgi cache
#fastcgi_cache_path /nginxcache levels=1:2 keys_zone=two:10m inactive=1d max_size=3000m;
#for example just for study! have fun!
include vhosts/api.yoho.cn.conf;
include vhosts/mapi.yohobuy.com.conf;
include vhosts/pay.yohobuy.com.conf;
include vhosts/service.yoho.cn.conf;
include vhosts/api_single.yoho.cn.conf;
include vhosts/unknown.conf;
}
... ...
... ... @@ -25,6 +25,8 @@ public interface HostInfoMapper {
List<HostInfo> selectHostInfosByTag(@Param("tag") String tag);
List<HostInfo> selectHostInfosByTagAndCloudType(@Param("tag") String tag,@Param("cloudType") int cloudType);
HostInfo selectByHostIp(@Param("hostIp") String hostIp);
}
\ No newline at end of file
... ...
... ... @@ -182,4 +182,11 @@
where instr(tags, LOWER(#{tag})) &gt; 0
</select>
<select id="selectHostInfosByTagAndCloudType" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from host_info
where instr(tags, LOWER(#{tag})) &gt; 0
AND cloud_type = #{cloudType}
</select>
</mapper>
\ No newline at end of file
... ...
... ... @@ -38,6 +38,10 @@
<artifactId>json-lib</artifactId>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
</dependencies>
... ...
... ... @@ -39,6 +39,16 @@ public class CommodUtil {
*/
public static final String LUA_SWITCH_SH = "switch_lua.sh";
/**
* 直连lua
*/
public static final String LB_SWITCH_SH = "switch_lb.sh";
/**
* 限流
*/
public static final String LIMIT_SWITCH_SH = "nginx_limit.sh";
public static String exe(String commond, String param) {
logger.info("start to exe commond:{},param:{}",commond,param);
Process process = null;
... ...
package com.monitor.switchs;
import com.google.common.collect.Maps;
import com.model.HostInfo;
import com.monitor.common.util.HandlebarsUtils;
import com.monitor.model.response.BaseResponse;
import com.monitor.mysql.mapper.HostInfoMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by zhouxiang on 2016/10/25.
*/
@Controller
@RequestMapping("lbswitch")
public class LbSwitchCtrl {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
HostInfoMapper hostInfoMapper;
private static final String OPENDL = "2a90dfa0f37b92aaebf369e9a4d38ba4";
private static final String CLOSEDL = "5b2d8b4b242e067616c6cd98851b2306";
/**
* 查看直连配置
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "viewConf")
@ResponseBody
public BaseResponse viewConf() throws Exception {
//直连的配置放在腾讯云nginx上
List<HostInfo> qcloudNginxHosts = hostInfoMapper.selectHostInfosByTag("lb-switch");
if (CollectionUtils.isEmpty(qcloudNginxHosts)) {
return new BaseResponse(500,"fail","没有找到直连nginx服务器");
}
return new BaseResponse(200,"success",analyseConfigFile(exe("view", qcloudNginxHosts.get(0).getHostIp(),null)));
}
/**
* 查看模板生成lb.lua脚本
*
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "viewToChangeLbConf")
@ResponseBody
public BaseResponse viewToChangeLuaConf(String status, HttpServletRequest request) throws Exception {
logger.info("will change status {}", status);
if(!StringUtils.equals("1", status) && !StringUtils.equals("0", status)){
throw new Exception("切换状态参数不正确!");
}
Map<String, Object> map = new HashMap();
map.put("open_dl", StringUtils.equals("1", status) ? OPENDL : CLOSEDL);
String path = request.getSession().getServletContext().getRealPath("/") + "lua/lb.lua";
String result = HandlebarsUtils.replace(map, "template/lb", path);
return new BaseResponse(200, "success", result);
}
/**
* 修改配置
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "switchConf")
@ResponseBody
public BaseResponse switchConf(HttpServletRequest request) {
String path = request.getSession().getServletContext().getRealPath("/") + "lua/lb.lua";
logger.info("lb.lua template path {}", path);
//lua dns 只放在腾讯云nginx服务器上
List<HostInfo> nginxHosts = hostInfoMapper.selectHostInfosByTag("lb-switch");
if (CollectionUtils.isEmpty(nginxHosts)) {
return new BaseResponse(500, "在cmdb中未找到直连对应的nginx服务器!");
}
List<String> ips = new ArrayList<String>();
for(HostInfo hostInfo : nginxHosts){
ips.add(hostInfo.getHostIp());
}
return new BaseResponse(200,"success", exe("switch", StringUtils.join(ips,","),path));
}
/**
* 执行命令
*
* @param commod
* @param host
* @param templatePath
* @return 2016年5月17日下午3:26:29
*/
public String exe(String commod, String host, String templatePath) {
StringBuilder commond = new StringBuilder();
commond.append(" " + commod).append(" " + host).append(" " + templatePath);
return CommodUtil.exe(CommodUtil.LB_SWITCH_SH, commond.toString());
}
private Map<String,String> analyseConfigFile(String rlt) {
String[] str = rlt.split("\r\n");
StringBuilder sb = new StringBuilder();
Map<String,String> result = Maps.newHashMap();
for (int i = 0; i < str.length; i++) {
if (str[i].indexOf("open_dl") != -1) {
if(i > 1 && StringUtils.isNotEmpty(str[i - 2]) && str[i - 2].contains("--")){
sb.append(str[i - 2]).append("</br>");
}
if(i > 0 && StringUtils.isNotEmpty(str[i - 1]) && str[i - 1].contains("--")){
sb.append(str[i - 1]).append("</br>");
}
sb.append(str[i]).append("</br>");
result.put("conf",sb.toString());
String dl = str[i].substring(str[i].indexOf("\"")).replaceAll("\"","").trim();
if(StringUtils.equals(OPENDL,dl)){
result.put("status","1");
return result;
}
if(StringUtils.equals(CLOSEDL,dl)){
result.put("status","0");
return result;
}
}
}
return result;
}
public static void main(String[] args) {
String s = "local open_dl = \"2a90dfa0f37b92aaebf369e9a4d38ba4\" ";
String b = s.substring(s.indexOf("\"")).replaceAll("\"","");
System.out.println(b);
}
}
... ...
package com.monitor.switchs;
import com.model.HostInfo;
import com.monitor.common.service.AlarmMsgService;
import com.monitor.common.util.HandlebarsUtils;
import com.monitor.model.domain.SmsTicket;
import com.monitor.model.response.BaseResponse;
import com.monitor.mysql.mapper.HostInfoMapper;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -11,6 +16,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
... ... @@ -32,6 +38,9 @@ public class LuaSwitchCtrl {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
HostInfoMapper hostInfoMapper;
/**
* 查看nginx配置
*
... ... @@ -39,16 +48,28 @@ public class LuaSwitchCtrl {
*/
@RequestMapping(value = "viewConf")
@ResponseBody
public String viewConf() {
// return "if not uid then" +
// "</br>return ngx.lookup_context.aws_ips_encrypt[domain]</br>" +
// "end</br>" +
// "if uid%1024>128 then</br>" +
// "return ngx.lookup_context.aws_ips_encrypt[domain]</br>" +
// "else</br>" +
// "return ngx.lookup_context.tencent_ips_encrypt[domain]</br>" +
// "end</br>";
return analyseConfigFile(exe("aws", "view"));
public String viewConf() throws Exception {
List<HostInfo> qcloudNginxHosts = hostInfoMapper.selectHostInfosByTag("lua-switch");
if (CollectionUtils.isEmpty(qcloudNginxHosts)) {
return "没有找到lua切换nginx服务器";
}
return analyseConfigFile(exe("view", qcloudNginxHosts.get(0).getHostIp(),null));
}
/**
* 查看nginx配置
*
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "viewToChangeLuaConf")
@ResponseBody
public BaseResponse viewToChangeLuaConf(String cloudName, HttpServletRequest request) {
logger.info("cloudName {}", cloudName);
Map<String, Object> map = new HashMap();
map.put("flag", StringUtils.equals("aws", cloudName) ? 1 : (StringUtils.equals("qcloud", cloudName) ? 2 : 3));
String path = request.getSession().getServletContext().getRealPath("/") + "lua/dns_resolver_worker.lua";
String result = HandlebarsUtils.replace(map, "template/dns_resolver_worker", path);
return new BaseResponse(200, "success", result);
}
/**
... ... @@ -58,25 +79,33 @@ public class LuaSwitchCtrl {
*/
@RequestMapping(value = "switchConf")
@ResponseBody
public BaseResponse switchConf(String cloudName) {
String result = exe(cloudName, "switch");
BaseResponse<String> baseResponse = new BaseResponse<>();
baseResponse.setCode(200);
baseResponse.setData(result);
return baseResponse;
public BaseResponse switchConf(HttpServletRequest request) {
String path = request.getSession().getServletContext().getRealPath("/") + "lua/dns_resolver_worker.lua";
logger.info("path {}", path);
//lua dns 只放在腾讯云nginx服务器上
List<HostInfo> nginxHosts = hostInfoMapper.selectHostInfosByTag("lua-switch");
if (CollectionUtils.isEmpty(nginxHosts)) {
return new BaseResponse(500, "腾讯云在cmdb中未找到对应的nginx服务器!");
}
List<String> ips = new ArrayList<String>();
for(HostInfo hostInfo : nginxHosts){
ips.add(hostInfo.getHostIp());
}
return new BaseResponse(200,"success", exe("switch", org.apache.commons.lang.StringUtils.join(ips,","),path));
}
/**
* 执行命令
*
* @param cloudName
* @param commod
* @param host
* @param templatePath
* @return 2016年5月17日下午3:26:29
*/
public String exe(String cloudName, String commod) {
public String exe(String commod, String host, String templatePath) {
StringBuilder commond = new StringBuilder();
commond.append(" -e " + commod);
commond.append(" -s " + cloudName);
commond.append(" " + commod).append(" " + host).append(" " + templatePath);
return CommodUtil.exe(CommodUtil.LUA_SWITCH_SH, commond.toString());
}
... ... @@ -85,7 +114,7 @@ public class LuaSwitchCtrl {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length; i++) {
if (str[i].indexOf("cloud_flag") != -1) {
sb.append(str[i-1]).append("</br>");
sb.append(str[i - 1]).append("</br>");
sb.append(str[i]).append("</br>");
}
}
... ...
package com.monitor.switchs;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.model.HostInfo;
import com.monitor.common.util.HandlebarsUtils;
import com.monitor.model.response.BaseResponse;
import com.monitor.mysql.mapper.HostInfoMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by zhouxiang on 2016/10/25.
*/
@Controller
@RequestMapping("limitswitch")
public class NginxLimit {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
HostInfoMapper hostInfoMapper;
/**
* 查看nginx配置
*
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "viewConf")
@ResponseBody
public BaseResponse viewConf() throws Exception {
List<HostInfo> qcloudNginxHosts = hostInfoMapper.selectHostInfosByTag("limit-switch");
if (CollectionUtils.isEmpty(qcloudNginxHosts)) {
return new BaseResponse(500,"fail","没有找到限流的nginx服务器");
}
return new BaseResponse(200,"success",analyseConfigFile(exe("view", qcloudNginxHosts.get(0).getHostIp(),null)));
}
/**
* 查看nginx配置
*
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "viewToChangeLimitConf")
@ResponseBody
public BaseResponse viewToChangeLuaConf(@RequestBody Map<String,String> params, HttpServletRequest request) {
logger.info("params {}", params);
Map<String, Object> map = new HashMap();
map.put("open_limit_flow", params.get("limitFlow"));
List apiConfigList = JSON.parseArray(params.get("apiConfs"),String.class);
int apiConfigSize = apiConfigList.size();
for(int i = 0;i< apiConfigSize;i++){
if(i == (apiConfigSize -1)){
break;
}
apiConfigList.set(i,apiConfigList.get(i)+",");
}
map.put("limit_config", apiConfigList);
List serviceConfList = JSON.parseArray(params.get("serviceConfs"),String.class);
int serviceConfSize = serviceConfList.size();
for(int i = 0;i< serviceConfSize;i++){
if(i == (serviceConfSize -1)){
break;
}
serviceConfList.set(i,serviceConfList.get(i)+",");
}
map.put("limit_service_config", serviceConfList);
String path = request.getSession().getServletContext().getRealPath("/") + "lua/init_lua.lua";
String result = HandlebarsUtils.replace(map, "template/init_lua", path);
return new BaseResponse(200, "success", result);
}
/**
* 修改配置
* type:环境类型 1:线上 2:灰度
*
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "switchConf")
@ResponseBody
public BaseResponse switchNginxConf(HttpServletRequest httpRequest) {
//获取对应cloud的机器 aws 1 qcloud 2
List<HostInfo> nginxHosts = hostInfoMapper.selectHostInfosByTag("limit-switch");
if (CollectionUtils.isEmpty(nginxHosts)) {
return new BaseResponse(500, "在cmdb中未找到限流对应的nginx服务器!");
}
List<String> ips = new ArrayList<String>();
for(HostInfo hostInfo : nginxHosts){
ips.add(hostInfo.getHostIp());
}
String tempPath = httpRequest.getSession().getServletContext().getRealPath("/") + "lua/init_lua.lua";
return new BaseResponse(200,"success", exe("switch", StringUtils.join(ips,","),tempPath));
}
/**
* 执行命令
*
* @param commod
* @param host
* @param templatePath
* @return 2016年5月17日下午3:26:29
*/
public String exe(String commod, String host, String templatePath) {
StringBuilder commond = new StringBuilder();
commond.append(" " + commod).append(" " + host).append(" " + templatePath);
return CommodUtil.exe(CommodUtil.LIMIT_SWITCH_SH, commond.toString());
}
private Map<String,Object> analyseConfigFile(String str) throws IOException {
String[] strs = str.split("\r\n");
Map<String,Object> map = Maps.newHashMap();
for(int i = 0; i< strs.length ; i++){
if(map.keySet().containsAll(Lists.newArrayList("limit_flow","limit_config","limit_service_config"))){
break;
}
if(strs[i].contains("open_limit_flow")){
map.put("open_limit_flow",strs[i].trim().split("=")[1]);
continue;
}
if(strs[i].contains("limit_config") || strs[i].contains("limit_service_config")){
List<String> limitConf = Lists.newArrayList();
String key = strs[i].contains("limit_config") ? "limit_config" : "limit_service_config";
while (true){
i++;
if(!strs[i].trim().startsWith("[") && strs[i].trim().endsWith("}")){
break;
}
if(StringUtils.isEmpty(strs[i].trim()) || strs[i].trim().startsWith("--")){
continue;
}
limitConf.add(strs[i].trim().replace("},","}"));
}
map.put(key, limitConf);
continue;
}
}
return map;
}
}
... ...
package com.monitor.switchs;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.model.HostInfo;
import com.monitor.common.service.AlarmMsgService;
import com.monitor.common.util.HandlebarsUtils;
import com.monitor.common.util.RandomUtil;
import com.monitor.model.domain.SmsTicket;
import com.monitor.model.response.BaseResponse;
import com.monitor.mysql.mapper.HostInfoMapper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -12,6 +23,7 @@ import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
... ... @@ -33,6 +45,9 @@ public class NginxSwitchCtrl {
@Value("${system.envi}")
private String env;
@Autowired
HostInfoMapper hostInfoMapper;
/**
* 查看nginx配置
*
... ... @@ -41,49 +56,125 @@ public class NginxSwitchCtrl {
@RequestMapping(value = "viewNginxConf")
@ResponseBody
public BaseResponse viewNginxConf() {
Map<String,List<Map<String, Object>>> map = new HashMap<>();
if ("test".equals(env)) {
Map<String, List<Map<String, Object>>> map = new HashMap<>();
/*if ("test".equals(env)) {
List<Map<String, Object>> awsList = localTest("aws");
List<Map<String, Object>> qcloudList = localTest("qq");
map.put("awsList", awsList);
map.put("qcloudList", qcloudList);
return new BaseResponse(map);
}*/
List<HostInfo> awsNginxHosts = hostInfoMapper.selectHostInfosByTagAndCloudType("upstream-switch", 1);
if(CollectionUtils.isEmpty(awsNginxHosts)){
map.put("awsList", Lists.newArrayList());
}else {
List<Map<String, Object>> awsList = analyseConfigFile(exe("view", awsNginxHosts.get(0).getHostIp(), null));
map.put("awsList", awsList);
}
List<HostInfo> qcloudNginxHosts = hostInfoMapper.selectHostInfosByTagAndCloudType("upstream-switch", 2);
if(CollectionUtils.isEmpty(qcloudNginxHosts)){
map.put("qcloudList", Lists.newArrayList());
}else {
List<Map<String, Object>> qcloudList = analyseConfigFile(exe("view", qcloudNginxHosts.get(0).getHostIp(), null));
map.put("qcloudList", qcloudList);
}
List<Map<String, Object>> awsList = analyseConfigFile(exe("aws", "view", null));
List<Map<String, Object>> qcloudList = analyseConfigFile(exe("qcloud", "view", null));
map.put("awsList", awsList);
map.put("qcloudList", qcloudList);
return new BaseResponse(map);
}
/**
* 修改配置
* type:环境类型 1:线上 2:灰度
*
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "viewToChangeNginxConf")
@ResponseBody
public BaseResponse viewToChangeNginxConf(String cloudName, String target, String ips, String onlineOrGray, HttpServletRequest httpRequest) {
//切线上 灰度ips不能为空
if (StringUtils.isEmpty(ips)) {
return new BaseResponse(500, "线上或灰度服务器入参不能为空!");
}
//线上切换
String tag = StringUtils.equals("gray", target) ? "灰度" : "gateway";
//需要查询的gateway机子
int gatewayCloudType = StringUtils.equals("aws", target) ? 1 : (StringUtils.equals("qcloud", target) ? 2 : (StringUtils.equals("aws", cloudName) ? 1 : 2));
//获取gateway或graygateway服务器
List<HostInfo> gatewayHosts = hostInfoMapper.selectHostInfosByTagAndCloudType(tag, gatewayCloudType);
if (CollectionUtils.isEmpty(gatewayHosts)) {
return new BaseResponse(500, cloudName + "在cmdb中未找到对应" + tag + "的服务器!");
}
//模板参数对象
Map<String, Object> map = new HashMap<String, Object>();
List<String> ipList = Lists.transform(gatewayHosts, new Function<HostInfo, String>() {
@Override
public String apply(HostInfo input) {
return input.getHostIp();
}
});
//切线上 灰度ips不变
if (StringUtils.equals("online", onlineOrGray)) {
map.put("grayips", JSON.parseArray(ips));
map.put("ips", ipList);
}
//切灰度 线上ips不变
else if (StringUtils.equals("gray", onlineOrGray)) {
map.put("ips", JSON.parseArray(ips));
map.put("grayips", ipList);
}
String path = httpRequest.getSession().getServletContext().getRealPath("/") + "java-nginx/" + cloudName + "/nginx.conf";
logger.info("nginx.conf create path is {}",path);
String result = HandlebarsUtils.replace(map, "template/" + cloudName + "-nginx", path);
Map<String,Object> resultMap = new HashMap();
resultMap.put("cloudName",cloudName);
resultMap.put("result",result);
return new BaseResponse(200, "success",resultMap);
}
/**
* 修改配置
* type:环境类型 1:线上 2:灰度
*
* @return 2016年5月12日下午1:49:48
*/
@RequestMapping(value = "switchNginxConf")
@ResponseBody
public BaseResponse switchNginxConf(String cloudName, String target) {
String result = exe(cloudName, "switch", target);
BaseResponse<String> baseResponse = new BaseResponse<>();
baseResponse.setCode(200);
baseResponse.setData(result);
return baseResponse;
public BaseResponse switchNginxConf(String cloudName, HttpServletRequest httpRequest) {
int nginxCloudType = StringUtils.equals("aws", cloudName) ? 1 : (StringUtils.equals("qcloud", cloudName) ? 2 : 0);
if (0 == nginxCloudType) {
return new BaseResponse(500, "没有匹配到要切换的云");
}
//获取对应cloud的机器 aws 1 qcloud 2
List<HostInfo> nginxHosts = hostInfoMapper.selectHostInfosByTagAndCloudType("upstream-switch", nginxCloudType);
if (CollectionUtils.isEmpty(nginxHosts)) {
return new BaseResponse(500, cloudName + "在cmdb中未找到对应的nginx服务器!");
}
List<String> ips = new ArrayList<String>();
for(HostInfo hostInfo : nginxHosts){
ips.add(hostInfo.getHostIp());
}
String tempPath = httpRequest.getSession().getServletContext().getRealPath("/") + "java-nginx/" + cloudName + "/nginx.conf";
return new BaseResponse(200,"success", exe("switch",StringUtils.join(ips,","),tempPath));
}
/**
* 执行命令
*
* @param cloudName
* @param commod
* @param host
* @param templatePath
* @return 2016年5月17日下午3:26:29
*/
public String exe(String cloudName, String commod, String target) {
public String exe(String commod, String host, String templatePath) {
StringBuilder commond = new StringBuilder();
commond.append(" -s " + cloudName);
commond.append(" -e " + commod);
commond.append(" -d " + target);
commond.append(" " + commod).append(" " + host).append(" " + templatePath);
return CommodUtil.exe(CommodUtil.NGINX_SWITCH_SH, commond.toString());
}
... ...