#!usr/bin/env python
# _*_ coding:utf-8 _*_
"""
@note: 自动注册服务
@author: jiashunx
@file: auto_register.py
@time: 2019/10/11
"""
import urllib2
import base64
from threading import Timer
class AutoRegister:
def __init__(self, req_model):
self.req_model = req_model
@staticmethod
def _get_request_models(apps):
req_models = []
for app in apps:
instance = app["instance"]
json_body = AutoRegister._get_request_json_body(instance=instance)
registers = app["registers"]
for register in registers:
username = None
password = None
if "username" in register:
username = register["username"]
if "password" in register:
password = register["password"]
req_models.append(RequestModel(
register_url=AutoRegister._format_register_url(register["url"]),
username=username,
password=password,
json_body=json_body,
instance=instance
))
return req_models
@staticmethod
def _format_register_url(url):
if url is not None and len(url) > 0:
if not url.endswith("/"):
url += "/"
if not url.endswith("eureka/"):
url += "eureka/"
return url
@staticmethod
def _get_request_json_body(instance):
ipAddr = instance["ipAddr"]
schema = "http://"
port = instance["port"]
if instance["securePortEnable"]:
schema = "https://"
port = instance["securePort"]
homePageUrl = schema + ipAddr + ":" + str(port) + "/"
statusPageUrl = homePageUrl + "Status"
healthCheckUrl = homePageUrl + "healthcheck"
return "<instance>" \
+ "<instanceId>" + instance["instanceId"] + "</instanceId>"\
+ "<hostName>" + instance["ipAddr"] + "</hostName>"\
+ "<app>" + instance["appId"] + "</app>"\
+ "<ipAddr>" + instance["ipAddr"] + "</ipAddr>"\
+ "<status>UP</status>"\
+ "<overriddenstatus>UNKNOWN</overriddenstatus>"\
+ "<port enable=\"" + str(instance["portEnable"]).lower() + "\">" + str(instance["port"]) + "</port>"\
+ "<securePort enabled=\"" + str(instance["securePortEnable"]).lower() + "\">" + str(instance["securePort"]) + "</securePort>"\
+ "<vipAddress>" + instance["vipAddress"] + "</vipAddress>"\
+ "<secureVipAddress>" + instance["secureVipAddress"] + "</secureVipAddress>"\
+ "<dataCenterInfo class=\"com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo\">"\
+ "<name>MyOwn</name>"\
+ "</dataCenterInfo>"\
+ "<metadata></metadata>"\
+ "<homePageUrl>" + homePageUrl + "</homePageUrl>"\
+ "<statusPageUrl>" + statusPageUrl + "</statusPageUrl>"\
+ "<healthCheckUrl>" + healthCheckUrl + "</healthCheckUrl>"\
+ "</instance>"
@staticmethod
def start(apps):
req_models = AutoRegister._get_request_models(apps)
for req_model in req_models:
AutoRegister(req_model=req_model)._auto_register()
def _auto_register(self):
self._register()
self._heartbeat()
def _get_authorization_value(self):
return "Basic " + base64.b64encode(str(self.req_model.username) + ":" + str(self.req_model.password))
def _register(self):
success = False
try:
request_url = self.req_model.register_url + "apps/" + self.req_model.appId
request = urllib2.Request(url=request_url, data=self.req_model.json_body, headers={
"Content-Type": "application/xml",
"Authorization": self._get_authorization_value()
})
request.get_method = lambda: "POST"
response = urllib2.urlopen(request)
if response.code == 204:
success = True
print("service:%s register success, target register-center: %s" % (str(self.req_model), self.req_model.register_url))
except Exception, e:
print("service:%s register failed, target register-center: %s, error reason: %s" % (str(self.req_model), self.req_model.register_url, str(e)))
finally:
return success
def _heartbeat(self):
success = False
try:
request_url = self.req_model.register_url + "apps/" + self.req_model.appId + "/" + self.req_model.instanceId
request = urllib2.Request(url=request_url, headers={
"Authorization": self._get_authorization_value()
})
request.get_method = lambda: "PUT"
response = urllib2.urlopen(request)
if response.code == 200:
success = True
print("service:%s heartbeat success, target register-center: %s" % (str(self.req_model), self.req_model.register_url))
except Exception, e:
print("service:%s heartbeat failed, target register-center: %s, error reason: %s" % (str(self.req_model), self.req_model.register_url, str(e)))
if not success:
print("service: %s heartbeat to register-center: %s failed, retry to register" % (str(self.req_model), self.req_model.register_url))
self._register()
# 心跳间隔-30s
Timer(30, self._heartbeat).start()
class RequestModel:
def __init__(self, register_url, username, password, json_body, instance):
self.register_url = register_url
self.username = username;
self.password = password;
self.json_body = json_body
self.instance = instance
self.appId = instance["appId"]
self.instanceId = instance["instanceId"]
def __str__(self):
return "{appId=%s, vipAddrss=%s, instanceId=%s}" % (self.instance["appId"], self.instance["vipAddress"], self.instance["instanceId"])
if __name__ == "__main__":
AutoRegister.start([
{
"instance": {
"appId": "appId",
"instanceId": "instanceId",
"vipAddress": "vipAddress",
"secureVipAddress": "vipAddress",
"ipAddr": "127.0.0.1",
"portEnable": True,
"port": 8080,
"securePortEnable": False,
"securePort": 443
},
"registers": [
{"url": "http://127.0.0.1:9081/"},
{"url": "http://127.0.0.1:9082/"}
]
},
{
"instance": {
"appId": "appId",
"instanceId": "instanceId",
"vipAddress": "vipAddress",
"secureVipAddress": "vipAddress",
"ipAddr": "127.0.0.1",
"portEnable": True,
"port": 8081,
"securePortEnable": False,
"securePort": 443
},
"registers": [
# 开启安全认证的注册中心,指定用户名及密码
# 注册中心可添加参数关闭安全认证: -Dspring.security.enabled=false
{"url": "http://127.0.0.1:9083/", "username": "admin", "password": "admin123"}
]
}
])
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。