dubbo内置哪几种服务容器_dubbo启动服务之容器(Container)
講解dubbo啟動服務的時候先來了解下java的spi機制
后期文章會首發于本專欄,歡迎關注
JAVA高級進階?zhuanlan.zhihu.com一:SPI 簡介
SPI 全稱為 (Service Provider Interface) ,是JDK內置的一種服務提供發現機制。 目前有不少框架用它來做服務的擴展發現, 簡單來說,它就是一種動態替換發現的機制, 舉個例子來說, 有個接口,想運行時動態的給它添加實現,你只需要添加一個實現,而后,把新加的實現,描述給JDK知道就行啦(通過改一個文本文件即可) ,公司內部目前Dubbo框架就基于SPI機制提供擴展功能。
代碼例子
public interface Cmand {public void execute();}public class ShutdownCommand implements Cmand {public void execute() {System.out.println("shutdown...."); }}public class StartCommand implements Cmand {public void execute() {System.out.println("start....");}}public class SPIMain {public static void main(String[] args) {ServiceLoader<Cmand> loader = ServiceLoader.load(Cmand.class);System.out.println(loader);for (Cmand Cmand : loader) {Cmand.execute();}}}配置:
com.unei.serviceloader.impl.ShutdownCommand
com.unei.serviceloader.impl.StartCommand
運行結果:
java.util.ServiceLoader[com.unei.serviceloader.Cmand]shutdown....start....相關原理解答
1.配置文件為什么要放在META-INF/services下面?
ServiceLoader類定義如下:
private static final String PREFIX = "META-INF/services/"; (JDK已經寫死了)
但是如果ServiceLoader在load時提供Classloader,則可以從其他的目錄讀取。
2.ServiceLoader讀取實現類是什么時候實例化的?
public void reload() {providers.clear();lookupIterator = new LazyIterator(service, loader);}private ServiceLoader(Class<S> svc, ClassLoader cl) {service = Objects.requireNonNull(svc, "Service interface cannot be null");loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;reload();}二:dubbo服務啟動之Container
1:dubbo幾大角色
Provider: 暴露服務的服務提供方。
Consumer: 調用遠程服務的服務消費方。
Registry: 服務注冊與發現的注冊中心。
Monitor: 統計服務的調用次調和調用時間的監控中心。
Container: 服務運行容器。
2:Container詳解
Dubbo的Container詳解模塊,是一個獨立的容器,因為服務通常不需要Tomcat/JBoss等Web容器的特性,沒必要用Web容器去加載服務。
服務容器只是一個簡單的Main方法,并加載一個簡單的Spring容器,用于暴露服務。
com.alibaba.dubbo.container.Main 是服務啟動的主類
了解Container接口有只有 start() stop()他的實現類
他的實現類有SpringContainer、Log4jContainer、JettyContainer、JavaConfigContainer、LogbackContainer。
當然你也可以自定義容器
官網:http://dubbo.io/Developer+Guide.htm#DeveloperGuide-ContainerSPI
Spring Container
自動加載META-INF/spring目錄下的所有Spring配置。 (這個在源碼里面已經寫死了DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml" 所以服務端的主配置放到META-INF/spring/這個目錄下)
配置:(配在java命令-D參數或者dubbo.properties中)
dubbo.spring.config=classpath*:META-INF/spring/*.xml ----配置spring配置加載位置Container
Jetty Container
啟動一個內嵌Jetty,用于匯報狀態。
配置:(配在java命令-D參數或者dubbo.properties中)
dubbo.jetty.port=8080 ----配置jetty啟動端口
dubbo.jetty.directory=/foo/bar ----配置可通過jetty直接訪問的目錄,用于存放靜態文件
dubbo.jetty.page=log,status,system ----配置顯示的頁面,缺省加載所有頁面
Log4j Container
自動配置log4j的配置,在多進程啟動時,自動給日志文件按進程分目錄。
配置:(配在java命令-D參數或者dubbo.properties中)
dubbo.log4j.file=/foo/bar.log ----配置日志文件路徑
dubbo.log4j.level=WARN ----配置日志級別
dubbo.log4j.subdirectory=20880 ----配置日志子目錄,用于多進程啟動,避免沖突
3:容器啟動
從上面的我們知道只需執行main方法就能啟動服務,那么默認到底是調用那個容器呢?
查看com.alibaba.dubbo.container.Container接口我們發現他上面有一個注解@SPI("spring")
知道默認調用的是com.alibaba.dubbo.container.spring.SpringContainer
這里main方法里面dubbo他們自定義了一個loader,叫ExtensionLoader
所以目前啟動容器的時候我們可以選:spring、javaconfig、jetty、log4j、logback等參數
4:容器停止
Dubbo是通過JDK的ShutdownHook來完成優雅停機的,所以如果用戶使用"kill -9 PID"等強制關閉指令,是不會執行優雅停機的,只有通過"kill PID"時,才會執行。
停止源碼(在Main方法里面):
if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {Runtime.getRuntime().addShutdownHook(new Thread() {public void run() {for (Container container : containers) {try {container.stop();logger.info("Dubbo " + container.getClass().getSimpleName() + " stopped!");} catch (Throwable t) {logger.error(t.getMessage(), t);}synchronized (Main.class) {running = false;Main.class.notify();}}}});}原理:
服務提供方
停止時,先標記為不接收新請求,新請求過來時直接報錯,讓客戶端重試其它機器。
然后,檢測線程池中的線程是否正在運行,如果有,等待所有線程執行完成,除非超時,則強制關閉。
服務消費方
停止時,不再發起新的調用請求,所有新的調用在客戶端即報錯。
然后,檢測有沒有請求的響應還沒有返回,等待響應返回,除非超時,則強制關閉。
5:服務jar打包
我這里用到了maven打,在pom文件里面添加以下內容
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib</classpathPrefix>
<mainClass>com.alibaba.dubbo.container.Main</mainClass>
<useUniqueVersions>false</useUniqueVersions>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>pre-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.demo.dubbox.service</groupId>
<artifactId>demo_order_api</artifactId>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWrite>true</overWrite>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<targetPath>${project.build.directory}/classes</targetPath>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<targetPath>${project.build.directory}/classes/META-INF/spring</targetPath>
<directory>src/main/resources/</directory>
<filtering>true</filtering>
<!-- 這個是主配置,把他打包到META-INF/spring/ 其他的xml都在spring-all.xml里面包含了 當然名字自定義-->
<includes>
<include>spring-all.xml</include>
</includes>
</resource>
</resources>
</build>
6:簡單啟動腳本
#!/bin/shJAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/HomeJAVA_OPTS="-Xms256m -Xmx512m"java -jar XXX.jar > "log.log" 2>&1最后,分享一份進階寶典《Java核心知識點整理.pdf》,覆蓋了JVM、Dubbo、鎖、高并發、反射、mybatis、Spring原理、微服務、Zookeeper、數據庫、數據結構等等,獲取請點擊下方文檔即可
Java高級架構學習資料分享+架構師成長之路?713dbae4.wiz03.com總結
以上是生活随笔為你收集整理的dubbo内置哪几种服务容器_dubbo启动服务之容器(Container)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 监控ui_做了10年监控系统,有些经验想
- 下一篇: 编制一个c语言成绩记录簿_C语言学到什么