java 服務屏蔽開關係統,可以手工降級服務,關閉服務 基於spring AOP機制,可以在特殊情況下屏蔽相關service類的某些返回,並且支持定義默認返回結果,隨機屏蔽某些異常服務。 通過啓動一個內置的http server來監聽外部指令。
對當前應用的影響。代碼請查看 https://github.com/zhwj184/autoswitch
使用指南:
1.在spring配置文件中添加如下,其中switch-service-pointcut是添加緊急情況下需要屏蔽的方法列表
<aop:config proxy-target-class="true"></aop:config>
<bean id="switchInteceptor" class="org.autoswitch.SwitchInteceptor">
</bean>
<bean id="switch-service-pointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<list>
<value>org.autoswitch.test.*</value>
</list>
</property>
</bean>
<aop:config>
<aop:advisor advice-ref="switchInteceptor" pointcut-ref="switch-service-pointcut"/>
</aop:config>
<bean id="wwitchControlHttpServer" class="org.autoswitch.SwitchControlHttpServer" init-method="init"></bean>
<bean id="testService" class="org.autoswitch.test.TestServiceImpl" />
<bean id="testController" class="org.autoswitch.test.TestController" />
例如下面的service,上面註釋分別是在應用啓動後手工屏蔽該服務調用,以後每次調用直接用參數的jsonResult反序列後返回, classmethod是具體到某個方法名稱,status爲open關閉該服務,close表示重新打開服務,jsonResult是mock返回結果的json串, 如果是基本類型,則必須用ret作爲key,其他list,bean之類的就直接用json串,type表示如果list有泛型的話則是返回的類完整類型;
public class TestServiceImpl implements TestService{
//http://localhost:8080/control/a.htm?classmethod=org.autoswitch.test.TestServiceImpl.hello&status=open&jsonResult=1
public void hello(){
System.out.println("hello");
}
//http://localhost:8080/control/a.htm?classmethod=org.autoswitch.test.TestServiceImpl.sayHello&status=open&jsonResult={ret:%22goodbuy%22}
public String sayHello(){
return "sayHello";
}
//http://localhost:8080/control/a.htm?classmethod=org.autoswitch.test.TestServiceImpl.getNames&status=open&jsonResult=[{"catList":[],"id":1,"name":"aaa"},{"catList":[],"id":1,"name":"aaa"},{"catList":[],"id":1,"name":"aaa"}]&type=org.autoswitch.test.TestBean
public List<TestBean> getNames(){
return null;
}
// http://localhost:8080/control/a.htm?classmethod=org.autoswitch.test.TestServiceImpl.getBeans&status=open&jsonResult={"catList":["123","456","789"],"id":1,"name":"aaa"} public TestBean getBeans(){ return null; }}
3調用示例代碼
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring-bean.xml");
TestService testControl = (TestService) context.getBean("testService");
try{
testControl.hello();
System.out.println(testControl.sayHello());
List<TestBean> list = testControl.getNames();
for(TestBean bean: list){
System.out.println(bean.getId() + bean.getName() + bean.getCatList());
}
TestBean bean = testControl.getBeans();
System.out.println(bean.getId() + bean.getName() + bean.getCatList());
}catch(Exception e){}
for(int i = 0; i < 10; i++){
try{
// testControl.hello();
System.out.println(testControl.sayHello());
// List<TestBean> list = testControl.getNames();
// for(TestBean bean: list){
// System.out.println(bean.getId() + bean.getName() + bean.getCatList());
// }
// TestBean bean = testControl.getBeans();
// System.out.println(bean.getId() + bean.getName() + bean.getCatList());
}catch(Exception e){
e.printStackTrace();
}
}
}
}
4.輸出
Listening on port 8080
hello
sayHello
Incoming connection from /127.0.0.1
New connection thread
goodbuy
goodbuy
Incoming connection from /127.0.0.1
New connection thread
sayHello
sayHello
sayHello
sayHello
sayHello
sayHello
sayHello
sayHello
這裏只是提供一種示例,如果要在生產環境中使用,則需要對併發控制,返回結果的序列化,方法名稱一致參數不一致等各種情況進行控制, 同時還需要對權限,後臺管理系統等可以做優化。