<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
公司運維繫統想要監控服務是否正常啟動,這些服務是k8s部署的,運維人員的要求業務服務提供一個http介面用於監控服務健康監測,要求所有的介面請求的URL,引數等都是相同的,這麼做的目的是不需要通過規範來約束開發人員去開一個服務健康監測的介面。
使用服務介面來檢測服務我覺得相比較監控程序啟動,埠監聽等方式更準確一些。所以,為了滿足運維同學的要求,起初想到的方案是提供一個jar,專門整合到專案中用於釋出監控介面,但是想了一下,這麼做需要涉及到服務的改造,我理想的方式是對應用無侵入的方式實現。
說到對應用無入侵,首先想到的就是javaagent
技術,此前使用該技術實現了無入侵增強程式紀錄檔的工具,所以對使用javaagent
已經沒有問題,此時需要考慮的是如何釋出介面了。
基礎技術 JavaAgent
支援的技術 SpringBoot和DubboX釋出的rest服務
公司服務大致分為兩類,一個是使用springboot
釋出的Spring MVC rest介面,另一種是基於DubboX
釋出的rest介面,因為公司在向服務網格轉,所以按要求是去dubbo化的,沒辦法還是有其他小組由於一些其他原因沒有或者說短期內不想進行服務改造的專案,這些專案比較老,不是springboot的,是使用spring+DubboX釋出的rest服務。所以這個agent要至少能支援這兩種技術。
支援SpringBoot
想要支援SpringBoot很簡單,因為SpringBoot支援自動裝配,所以,我要寫一個spring.factories
來進行自動裝配。
支援DubboX
業務系統是傳統spring+DubboX實現的,並不支援自動裝配,這是個問題點,還有個問題點就是如何也釋出一個DubboX的rest介面,這兩個問題實際上就需要對SpringBean生命週期和Dubbo介面釋出的流程有一定的瞭解了,這個一會兒再說。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.6.RELEASE</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <version>2.3.6.RELEASE</version> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>2.3.6.RELEASE</version> <optional>true</optional> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.70</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.6</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.7</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.8.4</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.0.1</version> </dependency> </dependencies>
實現一個JavaAgent很容易,以下三步就可以了,這裡不細說了。
定義JavaAgent入口
public class PreAgent { public static void premain(String args, Instrumentation inst) { System.out.println("輸入引數:" + args); // 通過引數控制,釋出的介面是DubboX還是SpringMVC Args.EXPORT_DUBBOX = args; } }
Maven打包設定
<plugins> <plugin> <artifactId>maven-deploy-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope> <promoteTransitiveDependencies>false</promoteTransitiveDependencies> <createDependencyReducedPom>true</createDependencyReducedPom> <minimizeJar>false</minimizeJar> <createSourcesJar>true</createSourcesJar> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Premain-Class>com.ruubypay.agent.PreAgent</Premain-Class> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins>
MANIFEST.MF編寫
注:該檔案在resource/META-INF/
目錄下
Manifest-Version: 1.0
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Premain-Class: com.ruubypay.agent.PreAgent
編寫Controller
介面很簡單就釋出一個get
介面,響應pong
即可。
@RestController public class PingServiceController { @GetMapping(value = "/agentServer/ping") public String ping() { return "pong"; } }
建立spring.factories
通過這個組態檔可以實現SpringBoot自動裝配,這裡不細說SpringBoot自動裝配的原理了,該檔案的設定內容就是要自動裝配的Bean
的全路徑,程式碼如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.ruubypay.config.WebConfiguration
WebConfiguration設定類
這個設定設定類很簡單,@Configuration
宣告這是個設定類,@ComponentScan
掃描包。
@Configuration @ComponentScan(value = "com.ruubypay") public class WebConfiguration { }
定義API
使用的是DubboX
釋出rest介面
需要javax.ws.rs
包的註解,@Produces({ContentType.APPLICATION_JSON_UTF_8})
宣告序列化方式,@Path
rest介面的路徑,@GET
宣告為get介面。
@Produces({ContentType.APPLICATION_JSON_UTF_8}) @Path("/agentServer") public interface IPingService { /** * ping介面 * @return */ @GET @Path("/ping") String ping(); }
編寫API實現類
@Component("IPingService") public class IPingServiceImpl implements IPingService { @Override public String ping() { return "pong"; } }
實現釋出Dubbo介面
如何實現釋出介面是實現的難點;首先程式並不支援自動裝配了,我們就要考慮如何獲取到Spring
上下文,如果能夠註冊Bean
到Spring容器
中,如何觸發釋出Dubbo介面
等問題。
Spring上下文獲取及註冊Bean到Spring容器中
觸發Bean註冊,獲取Spring上下文我們通過Spring的Aware介面可以實現,我這裡使用的是ApplicationContextAware
;註冊Bean
到Spring容器
中可以使用BeanDefinition
先建立Bean然後使用DefaultListableBeanFactory
的registerBeanDefinition
將BeanDefinition
註冊到Spring上下文中。
@Component public class AgentAware implements ApplicationContextAware { private static final String DUBBOX = "1"; private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; // 如果不是DubboX,不用釋出介面 if (DUBBOX.equals(Args.EXPORT_DUBBOX)) { // 註冊設定Bean WebConfiguration webConfiguration(); // 釋出DubboX介面 exportDubboxService(); } } public void webConfiguration() { System.out.println("建立WebConfiguration的bean"); ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext; DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory(); // 建立WebConfiguration的bean BeanDefinition webConfigurationBeanDefinition = new RootBeanDefinition(WebConfiguration.class); // 註冊到集合beanFactory中 System.out.println("註冊到集合beanFactory中"); listableBeanFactory.registerBeanDefinition(WebConfiguration.class.getName(), webConfigurationBeanDefinition); } }
釋出Dubbo介面
通過ApplicationContextAware
我們已經能夠獲取Spring上下文了,也就是說應用程式的Dubbo註冊中心,釋出介面協定,Dubbo Application等設定都已經存在Spring容器中了,我們只要拿過來使用即可,拿過來使用沒問題,我們接下來就需要考慮,如何釋出介面,這需要對Dubbo服務釋出的流程有一定的瞭解,這裡我不細說了,感興趣的可以自己瞭解下,或者看我以前釋出的文章;
首先Dubbo介面的Provider端的核心Bean是com.alibaba.dubbo.config.spring.ServiceBean
,使用Spring組態檔中的標籤<dubbo:service
標籤生成的Bean就是ServiceBean
,所以,這裡我們只需要建立ServiceBean
物件並且初始化物件中的必要資料,然後呼叫ServiceBean#export()
方法就可以釋出Dubbo服務了。
這裡需要的物件直接通過依賴查詢的方式從Spring容器獲取就可以了 ApplicationConfig
,ProtocolConfig
,RegistryConfig
,IPingService
。
public void exportDubboxService() { try { System.out.println("開始釋出dubbo介面"); // 獲取ApplicationConfig ApplicationConfig applicationConfig = applicationContext.getBean(ApplicationConfig.class); // 獲取ProtocolConfig ProtocolConfig protocolConfig = applicationContext.getBean(ProtocolConfig.class); // 獲取RegistryConfig RegistryConfig registryConfig = applicationContext.getBean(RegistryConfig.class); // 獲取IPingService介面 IPingService iPingService = applicationContext.getBean(IPingService.class); // 建立ServiceBean ServiceBean<IPingService> serviceBean = new ServiceBean<>(); serviceBean.setApplicationContext(applicationContext); serviceBean.setInterface("com.ruubypay.api.IPingService"); serviceBean.setApplication(applicationConfig); serviceBean.setProtocol(protocolConfig); serviceBean.setRegistry(registryConfig); serviceBean.setRef(iPingService); serviceBean.setTimeout(12000); serviceBean.setVersion("1.0.0"); serviceBean.setOwner("rubby"); // 釋出dubbo介面 serviceBean.export(); System.out.println("dubbo介面釋出完畢"); } catch (Exception e) { e.printStackTrace(); } }
這個工具實現起來不復雜,總也就六個類和一個介面,但其實實現其能力所涉及的支援還是比較考驗對框架的理解的,比如Spring生命週期,DubboX釋出介面的流程以及實現一個最簡單的JavaAgent的方式。
到此這篇關於JavaAgent實現http介面釋出方式淺析的文章就介紹到這了,更多相關JavaAgent http介面內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45