前一篇文章已經把spy2servers的用戶使用手冊整理出來了,這次更新主要是把開發手冊部分的整理。
如果沒有下載的朋友可以從下面下載spy2servers。
1. 下載
下載地址:
二進制程序
第三方類庫下載,第三方類庫下載2 Jetty類庫 放到lib目錄下。
api-docs
源代碼
開發手冊:
spy2servers對外提供三個組件接口,分別SpyComponent, AlertComponent和MessageAlertChannelActiveAwareComponent
下面是接口的實現類圖:
SpyComponent

AlertComponent

MessageAlertChannelActiveAwareComponent

SpyComponet接口提供監控組件的功能。我們可以直接去實現該接口即可。不過為了方便 spy2servers還提供AbstractSpyComponent抽象類
幫助我們更快速的開發。
下面來簡單的根據來實現一個SimpleSpyComponent.功能很簡單,就是每5秒鐘發送一個監控消息。
SimpleSpyComponent繼承AbstractSpyComponent。
下面源代碼:因為實現非常簡單,我就不解釋了。
1 import java.util.Date;
2 import java.util.UUID;
3
4 import org.xmatthew.spy2servers.core.AbstractSpyComponent;
5 import org.xmatthew.spy2servers.core.Message;
6
7 /**
8 * @author Matthew Xie
9 *
10 */
11 public class SimpleSpyComponent extends AbstractSpyComponent {
12
13 private boolean started;
14
15 /* (non-Javadoc)
16 * @see org.xmatthew.spy2servers.core.Component#startup()
17 */
18 public void startup() {
19
20 started = true;
21 setStatusRun();
22 try {
23 while (started) {
24 onSpy(createMessage());
25 Thread.sleep(5000);
26 }
27 } catch (Exception e) {
28 e.printStackTrace();
29 }
30 }
31
32 private Message createMessage() {
33 Message message = new Message();
34 message.setId(UUID.randomUUID().toString());
35 message.setCreateDate(new Date());
36 message.setDescription("message sent by " + getName());
37 message.setLevel(Message.LV_INFO);
38 message.setType("Test Message");
39 return message;
40 }
41
42 public void stop() {
43 started = false;
44 setStatusStop();
45 }
46
47 }
2 import java.util.UUID;
3
4 import org.xmatthew.spy2servers.core.AbstractSpyComponent;
5 import org.xmatthew.spy2servers.core.Message;
6
7 /**
8 * @author Matthew Xie
9 *
10 */
11 public class SimpleSpyComponent extends AbstractSpyComponent {
12
13 private boolean started;
14
15 /* (non-Javadoc)
16 * @see org.xmatthew.spy2servers.core.Component#startup()
17 */
18 public void startup() {
19
20 started = true;
21 setStatusRun();
22 try {
23 while (started) {
24 onSpy(createMessage());
25 Thread.sleep(5000);
26 }
27 } catch (Exception e) {
28 e.printStackTrace();
29 }
30 }
31
32 private Message createMessage() {
33 Message message = new Message();
34 message.setId(UUID.randomUUID().toString());
35 message.setCreateDate(new Date());
36 message.setDescription("message sent by " + getName());
37 message.setLevel(Message.LV_INFO);
38 message.setType("Test Message");
39 return message;
40 }
41
42 public void stop() {
43 started = false;
44 setStatusStop();
45 }
46
47 }
好了,現在我實現一個監控組件,讓我們再來實現一個報警組件SimpleAlertComponet,它繼承AbstractAlertComponent抽象類。
下面是實現的源代碼:功能也是超簡單,就是如果組件的狀態正常,則從屏幕輸出Message消息內容
1 import org.xmatthew.spy2servers.core.AbstractAlertComponent;
2 import org.xmatthew.spy2servers.core.Message;
3
4 /**
5 * @author Matthew Xie
6 *
7 */
8 public class SimpleAlertComponet extends AbstractAlertComponent{
9
10 private boolean started;
11
12 @Override
13 protected void onAlert(Message message) {
14 if (started) {
15 System.out.println(message);
16 }
17 }
18
19 public void startup() {
20
21 started = true;
22 setStatusRun();
23
24 }
25
26 public void stop() {
27 started = false;
28 setStatusStop();
29
30 }
31
32 }
2 import org.xmatthew.spy2servers.core.Message;
3
4 /**
5 * @author Matthew Xie
6 *
7 */
8 public class SimpleAlertComponet extends AbstractAlertComponent{
9
10 private boolean started;
11
12 @Override
13 protected void onAlert(Message message) {
14 if (started) {
15 System.out.println(message);
16 }
17 }
18
19 public void startup() {
20
21 started = true;
22 setStatusRun();
23
24 }
25
26 public void stop() {
27 started = false;
28 setStatusStop();
29
30 }
31
32 }
接下來我們來實現MessageAlertChannelActiveAwareComponent組件。它的功能是消息調度監控組件接口,提供消息調度監控的管理。
我們知道JmxServiceComponent組件就實現該接口,通過JMX服務提供消息調度情況。
下面是實現的源代碼,只是把每次調試的消息打印出來
1 import java.util.Collections;
2 import java.util.LinkedList;
3 import java.util.List;
4
5 import org.xmatthew.spy2servers.core.AbstractComponent;
6 import org.xmatthew.spy2servers.core.MessageAlertChannel;
7 import org.xmatthew.spy2servers.core.MessageAlertChannelActiveAwareComponent;
8
9 /**
10 * @author Matthew Xie
11 *
12 */
13 public class SimpleChannelAwareComponent extends AbstractComponent implements
14 MessageAlertChannelActiveAwareComponent {
15
16 private boolean started;
17
18 private List<MessageAlertChannel> channels = Collections.synchronizedList(new LinkedList<MessageAlertChannel>());
19
20 public List<MessageAlertChannel> getChannels() {
21 return channels;
22 }
23
24 public void onMessageAlertChannelActive(MessageAlertChannel channel) {
25 if (!started) {
26 return;
27 }
28 channels.add(channel);
29 printChannel(channel);
30 }
31
32 public void startup() {
33 started = true;
34 setStatusRun();
35
36 }
37
38 public void stop() {
39 started = false;
40 setStatusStop();
41
42 }
43
44 private void printChannel(MessageAlertChannel channel) {
45 if (channel != null) {
46 System.out.println("channel aware component say:");
47 System.out.print("spyComponent is: ");
48 System.out.println(channel.getSpyComponent());
49 System.out.print("alertComponent is: ");
50 System.out.println(channel.getAlertComponent());
51 System.out.print("message is: ");
52 System.out.println(channel.getMessage());
53 }
54 }
55
56
57 }
2 import java.util.LinkedList;
3 import java.util.List;
4
5 import org.xmatthew.spy2servers.core.AbstractComponent;
6 import org.xmatthew.spy2servers.core.MessageAlertChannel;
7 import org.xmatthew.spy2servers.core.MessageAlertChannelActiveAwareComponent;
8
9 /**
10 * @author Matthew Xie
11 *
12 */
13 public class SimpleChannelAwareComponent extends AbstractComponent implements
14 MessageAlertChannelActiveAwareComponent {
15
16 private boolean started;
17
18 private List<MessageAlertChannel> channels = Collections.synchronizedList(new LinkedList<MessageAlertChannel>());
19
20 public List<MessageAlertChannel> getChannels() {
21 return channels;
22 }
23
24 public void onMessageAlertChannelActive(MessageAlertChannel channel) {
25 if (!started) {
26 return;
27 }
28 channels.add(channel);
29 printChannel(channel);
30 }
31
32 public void startup() {
33 started = true;
34 setStatusRun();
35
36 }
37
38 public void stop() {
39 started = false;
40 setStatusStop();
41
42 }
43
44 private void printChannel(MessageAlertChannel channel) {
45 if (channel != null) {
46 System.out.println("channel aware component say:");
47 System.out.print("spyComponent is: ");
48 System.out.println(channel.getSpyComponent());
49 System.out.print("alertComponent is: ");
50 System.out.println(channel.getAlertComponent());
51 System.out.print("message is: ");
52 System.out.println(channel.getMessage());
53 }
54 }
55
56
57 }
ok,接下來我們來配置spy2servers.xml文件使用它工作起來。
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.xmatthew.org/spy2servers/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.xmatthew.org/spy2servers/schema
http://www.xmatthew.org/spy2servers/schema/spy2servers-1.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.0.xsd">
<core-component> <!-- 配置核組件,這個必須要有 -->
<simple-alertRule> <!-- 配置 消息報警機制-->
<channel>
<from value="mySpyComponent"/>
<to value="myAlertComponent"/>
</channel>
</simple-alertRule>
</core-component>
<jmxService-component/> <!-- 開啟jmx監控服務,其IP通過 java啟動命令設置 默認為1616 -->
<!-- 定義 SimpleSpyComponent組件-->
<beans:bean class="org.xmatthew.mypractise.SimpleSpyComponent">
<beans:property name="name" value="mySpyComponent"></beans:property>
</beans:bean>
<!-- 定義 SimpleAlertComonent 組件-->
<beans:bean class="org.xmatthew.mypractise.SimpleAlertComponet">
<beans:property name="name" value="myAlertComponent"></beans:property>
</beans:bean>
<!-- 定義 SimpleChannelAwareComponent 組件-->
<beans:bean class="org.xmatthew.mypractise.SimpleChannelAwareComponent">
<beans:property name="name" value="SimpleChannelAwareComponent"></beans:property>
</beans:bean>
<jetty> <!-- 配置內置服務器 -->
<connectors>
<nioConnector port="7758" /> <!-- using nio connector port is 7758 -->
</connectors>
<handlers>
<!-- 配置內置基于web 方式的平臺組件監控 servlet context為 /admin -->
<servlet servletClass="org.xmatthew.spy2servers.component.web.ComponentsViewServlet" path="/admin" />
</handlers>
</jetty>
</beans:beans>
<beans:beans xmlns="http://www.xmatthew.org/spy2servers/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.xmatthew.org/spy2servers/schema
http://www.xmatthew.org/spy2servers/schema/spy2servers-1.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.0.xsd">
<core-component> <!-- 配置核組件,這個必須要有 -->
<simple-alertRule> <!-- 配置 消息報警機制-->
<channel>
<from value="mySpyComponent"/>
<to value="myAlertComponent"/>
</channel>
</simple-alertRule>
</core-component>
<jmxService-component/> <!-- 開啟jmx監控服務,其IP通過 java啟動命令設置 默認為1616 -->
<!-- 定義 SimpleSpyComponent組件-->
<beans:bean class="org.xmatthew.mypractise.SimpleSpyComponent">
<beans:property name="name" value="mySpyComponent"></beans:property>
</beans:bean>
<!-- 定義 SimpleAlertComonent 組件-->
<beans:bean class="org.xmatthew.mypractise.SimpleAlertComponet">
<beans:property name="name" value="myAlertComponent"></beans:property>
</beans:bean>
<!-- 定義 SimpleChannelAwareComponent 組件-->
<beans:bean class="org.xmatthew.mypractise.SimpleChannelAwareComponent">
<beans:property name="name" value="SimpleChannelAwareComponent"></beans:property>
</beans:bean>
<jetty> <!-- 配置內置服務器 -->
<connectors>
<nioConnector port="7758" /> <!-- using nio connector port is 7758 -->
</connectors>
<handlers>
<!-- 配置內置基于web 方式的平臺組件監控 servlet context為 /admin -->
<servlet servletClass="org.xmatthew.spy2servers.component.web.ComponentsViewServlet" path="/admin" />
</handlers>
</jetty>
</beans:beans>
好了,現在我們運行start.sh啟動看一下效果
INFO Main - Server starting
INFO log - Logging to org.slf4j.impl.JCLLoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog
INFO CoreComponent - plug component CoreComponent
INFO CoreComponent - plug component JmxServiceComponent
INFO CoreComponent - plug component mySpyComponent
INFO CoreComponent - plug component myAlertComponent
INFO CoreComponent - plug component SimpleChannelAwareComponent
INFO log - jetty-6.1.4

INFO log - Logging to org.slf4j.impl.JCLLoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog
INFO CoreComponent - plug component CoreComponent
INFO CoreComponent - plug component JmxServiceComponent
INFO CoreComponent - plug component mySpyComponent
INFO CoreComponent - plug component myAlertComponent
INFO CoreComponent - plug component SimpleChannelAwareComponent
INFO log - jetty-6.1.4
沒問題我們的組件已經運行起來,接下就是五秒輸出結果:
channel aware component say:
spyComponent is: org.xmatthew.mypractise.SimpleSpyComponent@193385d
alertComponent is: org.xmatthew.mypractise.SimpleAlertComponet@5973ea
message is: org.xmatthew.spy2servers.core.Message@171f189[id=cb8c02c8-62b3-4c7f-8dc3-aea41382c178,body=<null>,level=4,properties={},createDate=Fri Apr 25 22:39:24 CST 2008,description=message sent by mySpyComponent,type=Test Message]
org.xmatthew.spy2servers.core.Message@1a897a9[id=52a954ef-2b3b-4374-a257-e3f3a9b5e209,body=<null>,level=4,properties={from=mySpyComponent, to=myAlertComponent},createDate=Fri Apr 25 22:39:29 CST 2008,description=message sent by mySpyComponent,type=Test Message]
channel aware component say:
spyComponent is: org.xmatthew.mypractise.SimpleSpyComponent@193385d
alertComponent is: org.xmatthew.mypractise.SimpleAlertComponet@5973ea
message is: org.xmatthew.spy2servers.core.Message@17cec96[id=52a954ef-2b3b-4374-a257-e3f3a9b5e209,body=<null>,level=4,properties={},createDate=Fri Apr 25 22:39:29 CST 2008,description=message sent by mySpyComponent,type=Test Message]
org.xmatthew.spy2servers.core.Message@1947496[id=548c0c9f-0aa5-480d-a91b-b0a6d98d4aeb,body=<null>,level=4,properties={from=mySpyComponent, to=myAlertComponent},createDate=Fri Apr 25 22:39:34 CST 2008,description=message sent by mySpyComponent,type=Test Message]
spyComponent is: org.xmatthew.mypractise.SimpleSpyComponent@193385d
alertComponent is: org.xmatthew.mypractise.SimpleAlertComponet@5973ea
message is: org.xmatthew.spy2servers.core.Message@171f189[id=cb8c02c8-62b3-4c7f-8dc3-aea41382c178,body=<null>,level=4,properties={},createDate=Fri Apr 25 22:39:24 CST 2008,description=message sent by mySpyComponent,type=Test Message]
org.xmatthew.spy2servers.core.Message@1a897a9[id=52a954ef-2b3b-4374-a257-e3f3a9b5e209,body=<null>,level=4,properties={from=mySpyComponent, to=myAlertComponent},createDate=Fri Apr 25 22:39:29 CST 2008,description=message sent by mySpyComponent,type=Test Message]
channel aware component say:
spyComponent is: org.xmatthew.mypractise.SimpleSpyComponent@193385d
alertComponent is: org.xmatthew.mypractise.SimpleAlertComponet@5973ea
message is: org.xmatthew.spy2servers.core.Message@17cec96[id=52a954ef-2b3b-4374-a257-e3f3a9b5e209,body=<null>,level=4,properties={},createDate=Fri Apr 25 22:39:29 CST 2008,description=message sent by mySpyComponent,type=Test Message]
org.xmatthew.spy2servers.core.Message@1947496[id=548c0c9f-0aa5-480d-a91b-b0a6d98d4aeb,body=<null>,level=4,properties={from=mySpyComponent, to=myAlertComponent},createDate=Fri Apr 25 22:39:34 CST 2008,description=message sent by mySpyComponent,type=Test Message]
可以使用JMX或是進入web管理頁面查看組件的狀態。
大功告成,我們已經對spy2serves平臺提供三個組件都做了簡單實現。
如果有什么問題歡迎大家給我留言。
Good Luck!
Yours Matthew!
2008年4月25日