Dubbo基礎入門知識點
Dubbo
1. 簡介
分散式:分散式系統是一個硬體或軟體元件分佈在不同的網路計算機上,彼此之間僅僅通過訊息傳遞進行通訊和協調的系統。
- 這是經典的分散式著作《分散式系統概念與設計》中的定義。其實在我的理解裡,就是把一個大的系統拆分成很多個業務模組,並部署在多臺網路計算機上。就是把集中式的中心節點拆分為多個節點去完成單箇中心節點的工作。
RPC:通訊 序列化
<!--匯入依賴:dubbo + zookeeper -->
<!-- https://mvnrepository.com/artifact/org.apache.dubbo/dubbo-spring-boot-starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<!--zk client -->
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<!--日誌會衝突 -->
<!--引入zook -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.3</version>
<!--排除這個slf4j-log4j12-->
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
服務化最佳實踐
分包
建議將服務介面、服務模型、服務異常等均放在 API 包中,因為服務模型和異常也是 API 的一部分,這樣做也符合分包原則:重用釋出等價原則(REP),共同重用原則(CRP)。
如果需要,也可以考慮在 API 包中放置一份 Spring 的引用配置,這樣使用方只需在 Spring 載入過程中引用此配置即可。配置建議放在模組的包目錄下,以免衝突,
dubbo-monitor
從官網下載dubbo-monitor:dubbo官網
進行打包:
dubbo的監視器預設埠8080,開啟瀏覽器檢視
整合springboot
1.匯入依賴
dubbo-starter
其他依賴
<properties>
<java.version>1.8</java.version>
</properties>
<!--引入springboot整合dubbo的jar包-->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
application.yaml
//消費者
dubbo:
application:
name: boot-order-service-consumer
registry:
address: zookeeper://127.0.0.1:2181
monitor:
protocol: registry
//提供者
dubbo.application.name=boot-user-service-provider
dubbo.registry.address=127.0.0.1:2181
dubbo.registry.protocol=zookeeper
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
#連線監控中心
dubbo.monitor.protocol=registry
提供者
暴露服務用@Service
//使用dubbo提供的@Reference註解引用遠端服務
消費服務遠端引用就用@Reference 而不是@Autowired
覆蓋
JVM 啟動 -D 引數優先,這樣可以使使用者在部署和啟動時進行引數重寫,比如在啟動時需改變協議的埠。
XML 次之,如果在 XML 中有配置,則 dubbo.properties 中的相應配置項無效。
Properties 最後,相當於預設值,只有 XML 沒有配置時,dubbo.properties 的相應配置項才會生效,通常用於共享公共配置,比如應用名。
啟動時檢查
Dubbo 預設會在啟動時檢查依賴的服務是否可用,不可用時會丟擲異常,阻止 Spring 初始化完成,以便上線時,能及早發現問題,預設 check=“true”。
可以通過 check=“false” 關閉檢查,比如,測試時,有些服務不關心,或者出現了迴圈依賴,必須有一方先啟動。
另外,如果你的 Spring 容器是懶載入的,或者通過 API 程式設計延遲引用服務,請關閉 check,否則服務臨時不可用時,會丟擲異常,拿到 null 引用,如果 check=“false”,總是會返回引用,當服務恢復時,能自動連上。
以order-service-consumer
消費者為例,在consumer.xml中新增配置
關閉某個服務啟動時檢查 一個consumer <!-- 生成遠端服務代理,宣告需要呼叫的遠端服務的介面 -->
<dubbo:reference interface="com.hidisan.service.UserService" id="userService" check="false"/>
或者關閉所有服務啟動時檢查
<!--配置當前消費者的統一規則,當前所有的服務都不啟動時檢查-->
<dubbo:consumer check="false"></dubbo:consumer>
<!--這樣就是所有的reference的配置的check都是false-->
新增後,即使服務提供者不啟動,啟動當前的消費者,也不會出現錯誤
關閉註冊中心啟動時檢查(註冊訂閱失敗時報錯)
<dubbo:registry check="false" />
全域性超時配置
提供方返回時間過長,不然會導致執行緒阻塞
全域性超時配置
<dubbo:provider timeout="5000" />
<dubbo:consumer check="false" timeout="5000"></dubbo:consumer>
指定介面以及特定方法超時配置
<dubbo:provider interface="com.foo.BarService" timeout="2000">
<dubbo:method name="sayHello" timeout="3000" /> 指定方法的超時時間
</dubbo:provider>
配置的覆蓋規則:
- 方法級配置別優於介面級別,即小Scope優先
- Consumer端配置 優於 Provider配置 優於 全域性配置,
- 最後是Dubbo Hard Code的配置值(見配置文件
1、精確優選(放大>介面>全域性配置)
2、消費者配置優先(如果級別一樣,則消費者優先,提供者次之)
<!--retries="" :重試次數,不包含第一次呼叫-->
dubbo與springboot整合的三種方式
1、將服務提供者註冊到註冊中心(如何暴露服務)
1.1匯入Dubbo的依賴 和 zookeeper 客戶端
2、讓服務消費者去註冊中心訂閱服務提供者的服務地址
Springboot與Dubbo整合的三種方式
2.1匯入dubbo-starter。在application.properties配置屬性,使用@Service【暴露服務】,使用@Reference【引用服務】
2.2保留Dubbo 相關的xml配置檔案、匯入dubbo-starter,做到方法級別的精確
使用@ImportResource匯入Dubbo的xml配置檔案【@ImportResource(locations=“classpath:provider.xml”)】
3、使用 註解API的方式
將每一個元件手動配置到容器中,讓dubbo來掃描其他的元件,寫一個config包下的DubboConfig類
MyDubboConfig.java
@Configuration
public class MyDubboConfig {
// <dubbo:application name="boot-user-service-provider"/>
@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("boot-user-service-provider");
return applicationConfig;
}
//<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
@Bean
public RegistryConfig registryConfig(){
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress("zookeeper://127.0.0.1:2181");
/**
* registryConfig.setProtocol("zookeeper");
* registryConfig.setAddress("127.0.0.1:2181");
*/
return registryConfig;
}
//<dubbo:protocol name="dubbo" port="20880"/>
@Bean
public ProtocolConfig protocolConfig(){
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(20880);
return protocolConfig;
}
//<!-- 宣告需要暴露的服務介面 ref 指向服務真正的實現物件-->
// <dubbo:service interface="com.hidisan.service.UserService" ref="userServiceImpl" version="1.0.0" timeout="1000">
// <dubbo:method name="getUserAdressList" timeout="100"></dubbo:method>
// </dubbo:service>
@Bean
public ServiceConfig<UserService> userServiceConfig(UserService userService){
ServiceConfig<UserService> serviceConfig = new ServiceConfig<>();
serviceConfig.setInterface(UserService.class);
serviceConfig.setRef(userService);
serviceConfig.setVersion("1.0.0");
serviceConfig.setTimeout(1000);
//配置每一個method的資訊
MethodConfig methodConfig = new MethodConfig();
methodConfig.setName("getUserAdressList");
methodConfig.setTimeout(1000);
//將method設定關聯到service設定中
List<MethodConfig> methods = new ArrayList<>();
methods.add(methodConfig);
serviceConfig.setMethods(methods);
return serviceConfig;
}
}
@EnableDubbo(scanBasePackages = "com.hidisan")
@SpringBootApplication
public class BootOrderServiceConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(BootOrderServiceConsumerApplication.class, args);
}
}
2、高可用
zookeeper當機與dubbo原因:
健壯性↓
- 監控中心宕掉不影響使用,只是丟失部分取樣資料
- 資料庫宕掉後,註冊中心仍能通過快取提供服務列表查詢,但不能註冊新服務
- 註冊中心對等叢集,任意一臺宕掉後,將自動切換到另一臺
- 註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地快取通訊
- 服務提供者無狀態,任意一臺宕掉後,不影響使用
- 服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復
高可用:通過設計,減少系統不能提供服務的時間;
bo直連
現象:zookeeper註冊中心當機,還可以消費dubbo暴露的服務。
原因:
健壯性↓
監控中心宕掉不影響使用,只是丟失部分取樣資料
-
- 資料庫宕掉後,註冊中心仍能通過快取提供服務列表查詢,但不能註冊新服務
- 註冊中心對等叢集,任意一臺宕掉後,將自動切換到另一臺
- 註冊中心全部宕掉後,服務提供者和服務消費者仍能通過本地快取通訊
- 服務提供者無狀態,任意一臺宕掉後,不影響使用
- 服務提供者全部宕掉後,服務消費者應用將無法使用,並無限次重連等待服務提供者恢復
- 高可用:通過設計,減少系統不能提供服務的時間;
即使有註冊中心,也可以連線,通過dubbo直連
@Reference(url="127.0.0.1:20880") //dubbo直連
叢集下dubbo負載均衡配置
在叢集負載均衡時,Dubbo 提供了多種均衡策略,預設為 random 隨機呼叫
Random LoadBalance 基於權重的隨機負載均衡機制
隨機,按權重設定隨機概率。 在一個截面上碰撞的概率高,但呼叫量越大分佈越均勻,而且按概率使用權重後也比較均勻,有利於動態調整提供者權重。
RoundRobin LoadBalance 基於權重的輪詢負載均衡機制
輪循,按公約後的權重設定輪循比率。 存在慢的提供者累積請求的問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。
LeastActive LoadBalance最少活躍數負載均衡機制
最少活躍呼叫數,相同活躍數的隨機,活躍數指呼叫前後計數差。 使慢的提供者收到更少請求,因為越慢的提供者的呼叫前後計數差會越大。
ConsistentHash LoadBalance一致性hash 負載均衡機制
@Reference(loadbalance="randon/roundrobin") //設定輪詢方式
服務降級
當伺服器壓力劇增的情況下,根據實際業務情況及流量,對一些服務和頁面有策略的不處理或換種簡單的方式處理,從而釋放伺服器資源以保證核心交易正常運作或高效運作。
可以通過服務降級功能臨時遮蔽某個出錯的非關鍵服務,並定義降級後的返回策略。
mock=force:return+null 表示消費方對該服務的方法呼叫都直接返回 null 值,不發起遠端呼叫。用來遮蔽不重要服務不可用時對呼叫方的影響。
還可以改為 mock=fail:return+null 表示消費方對該服務的方法呼叫在失敗後,再返回 null 值,不拋異常。用來容忍不重要服務不穩定時對呼叫方的影響。
叢集容錯
Failover Cluster
失敗自動切換,當出現失敗,重試其它伺服器。通常用於讀操作,但重試會帶來更長延遲。可通過 retries=“2” 來設定重試次數(不含第一次)。重試次數配置如下:
<dubbo:service retries=“2” />
或
<dubbo:reference retries=“2” />
或
dubbo:reference
<dubbo:method name=“findFoo” retries=“2” />
</dubbo:reference>Failfast Cluster
快速失敗,只發起一次呼叫,失敗立即報錯。通常用於非冪等性的寫操作,比如新增記錄。Failsafe Cluster
失敗安全,出現異常時,直接忽略。通常用於寫入審計日誌等操作。Failback Cluster
失敗自動恢復,後臺記錄失敗請求,定時重發。通常用於訊息通知操作。Forking Cluster
並行呼叫多個伺服器,只要一個成功即返回。通常用於實時性要求較高的讀操作,但需要浪費更多服務資源。可通過 forks=“2” 來設定最大並行數。Broadcast Cluster
廣播呼叫所有提供者,逐個呼叫,任意一臺報錯則報錯 [2]。通常用於通知所有提供者更新快取或日誌等本地資源資訊。叢集模式配置
按照以下示例在服務提供方和消費方配置叢集模式
<dubbo:service cluster=“failsafe” />
或
<dubbo:reference cluster=“failsafe” />
整合hystrix
Hystrix 旨在通過控制那些訪問遠端系統、服務和第三方庫的節點,從而對延遲和故障提供更強大的容錯能力。Hystrix具備擁有回退機制和斷路器功能的執行緒和訊號隔離,請求快取和請求打包,以及監控和配置等功能
配置spring-cloud-starter-netflix-hystrix
spring boot官方提供了對hystrix的整合,直接在pom.xml里加入依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
然後在Application類上增加@EnableHystrix來啟用hystrix starter:
@SpringBootApplication
@EnableHystrix //開啟服務容錯功能
public class ProviderApplication {
...啟動方法
}
配置Provider端
在Dubbo的Provider上增加@HystrixCommand配置,這樣子呼叫就會經過Hystrix代理。
@Service(version = "1.0.0")
public class HelloServiceImpl implements HelloService {
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000") })
@Override
public String sayHello(String name) {
// System.out.println("async provider received: " + name);
// return "annotation: hello, " + name;
throw new RuntimeException("Exception to show hystrix enabled.");
}
}
配置Consumer端
對於Consumer端,則可以增加一層method呼叫,並在method上配置@HystrixCommand。當呼叫出錯時,會走到fallbackMethod = "reliable"的呼叫裡。
@Reference(version = "1.0.0")
private HelloService demoService;
@HystrixCommand(fallbackMethod = "reliable")
public String doSayHello(String name) {
return demoService.sayHello(name);
}
public String reliable(String name) {
return "hystrix fallback value";
}
3、dubbo原理
RPC原理
一次完整的RPC呼叫流程(同步呼叫,非同步另說)如下:
- 服務消費方(client)呼叫以本地呼叫方式呼叫服務;
- client stub接收到呼叫後負責將方法、引數等組裝成能夠進行網路傳輸的訊息體;
- client stub找到服務地址,並將訊息傳送到服務端;
- server stub收到訊息後進行解碼;
- server stub根據解碼結果呼叫本地的服務;
- 本地服務執行並將結果返回給server stub;
- server stub將返回結果打包成訊息併傳送至消費方;
- client stub接收到訊息,並進行解碼;
- 服務消費方得到最終結果。
dubbo只用了兩步1和8,中間的過程是透明的看不到的。RPC框架的目標就是要2~8這些步驟都封裝起來,這些細節對使用者來說是透明的,不可見的。
netty通訊原理
Netty是一個非同步事件驅動的網路應用程式框架, 用於快速開發可維護的高效能協議伺服器和客戶端。它極大地簡化並簡化了TCP和UDP套接字伺服器等網路程式設計。
BIO:(Blocking IO)
NIO (Non-Blocking IO)
也可以翻譯為 多路複用器,
Connect(連線就緒)、Accept(接受就緒)、Read(讀就緒)、Write(寫就緒)
netty基本原理
dubbo框架設計
config 配置層:對外配置介面,以 ServiceConfig, ReferenceConfig 為中心,可以直接初始化配置類,也可以通過 spring 解析配置生成配置類
proxy 服務代理層:服務介面透明代理,生成服務的客戶端 Stub 和伺服器端 Skeleton, 以 ServiceProxy 為中心,擴充套件介面為 ProxyFactory
registry 註冊中心層:封裝服務地址的註冊與發現,以服務 URL 為中心,擴充套件介面為 RegistryFactory, Registry, RegistryService
cluster 路由層:封裝多個提供者的路由及負載均衡,並橋接註冊中心,以 Invoker 為中心,擴充套件介面為 Cluster, Directory, Router, LoadBalance
monitor 監控層:RPC 呼叫次數和呼叫時間監控,以 Statistics 為中心,擴充套件介面為 MonitorFactory, Monitor, MonitorService
protocol 遠端呼叫層:封裝 RPC 呼叫,以 Invocation, Result 為中心,擴充套件介面為 Protocol, Invoker, Exporter
exchange 資訊交換層:封裝請求響應模式,同步轉非同步,以 Request, Response 為中心,擴充套件介面為 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
transport 網路傳輸層:抽象 mina 和 netty 為統一介面,以 Message 為中心,擴充套件介面為 Channel, Transporter, Client, Server, Codec
serialize 資料序列化層:可複用的一些工具,擴充套件介面為 Serialization, ObjectInput, ObjectOutput, ThreadPool
服務暴露
服務引用
4、關於dubbo的問題
- dubbo 通訊協議 dubbo 協議為什麼要消費者比提供者個數多:
因 dubbo 協議採用單一長連線,假設網路為千兆網路卡(1024Mbit=128MByte),
根據測試經驗資料每條連線最多隻能壓滿 7MByte(不同的環境可能不一樣,供參考),理論上 1 個服務提供者需要 20
個服務消費者才能壓滿網路卡。
- dubbo 通訊協議 dubbo 協議為什麼不能傳大包:
因 dubbo 協議採用單一長連線,
如果每次請求的資料包大小為 500KByte,假設網路為千兆網路卡(1024Mbit=128MByte),每條連線最大 7MByte(不同的
環境可能不一樣,供參考),
單個服務提供者的 TPS(每秒處理事務數)最大為:128MByte / 500KByte = 262。
單個消費者呼叫單個服務提供者的 TPS(每秒處理事務數)最大為:7MByte / 500KByte = 14。如果能接受,可以考慮使用,否則網路將成為瓶頸。
- dubbo 通訊協議 dubbo協議為什麼採用非同步單一長連線:
因為服務的現狀大都是服務提供者少,通常只有幾臺機器,
而服務的消費者多,可能整個網站都在訪問該服務,
比如 Morgan 的提供者只有 6 臺提供者,卻有上百臺消費者,每天有 1.5 億次呼叫,
如果採用常規的 hessian 服務,服務提供者很容易就被壓跨,
通過單一連線,保證單一消費者不會壓死提供者,
長連線,減少連線握手驗證等,
並使用非同步 IO,複用執行緒池,防止 C10K 問題。
- dubbo 通訊協議 dubbo 協議適用範圍和適用場景
適用範圍:傳入傳出引數資料包較小(建議小於 100K),消費者比提供者個數
多,單一消費者無法壓滿提供者,儘量不要用 dubbo 協議傳輸大檔案或超大字
符串。
適用場景:常規遠端服務方法呼叫
dubbo 協議補充:
連線個數:單連線
連線方式:長連線
傳輸協議:TCP
傳輸方式:NIO 非同步傳輸
序列化:Hessian 二進位制序列化
5.簡述dubbo
Dubbo是一個分散式服務框架,致力於提供高效能和透明化的RPC遠端服務呼叫方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,如果沒有分散式的需求,其實是不需要用的,只有在分散式的時候,才有dubbo這樣的分散式服務框架的需求,並且本質上是個服務呼叫的東西,說白了就是個遠端服務呼叫的分散式框架。
其核心部分包含:
-
遠端通訊: 提供對多種基於長連線的NIO框架抽象封裝,包括多種執行緒模型,序列化,以及“請求-響應”模式的資訊交換方式。
-
叢集容錯: 提供基於介面方法的透明遠端過程呼叫,包括多協議支援,以及軟負載均衡,失敗容錯,地址路由,動態配置等叢集支援。
-
自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查詢服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
6.Dubbo能做什麼?
1.透明化的遠端方法呼叫,就像呼叫本地方法一樣呼叫遠端方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬體負載均衡器,降低成本,減少單點。
3.服務自動註冊與發現,不再需要寫死服務提供方地址,註冊中心基於介面名查詢服務提供者的IP地址,並且能夠平滑新增或刪除服務提供者。
Dubbo採用全spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring載入Dubbo的配置即可,Dubbo基於Spring的Schema擴充套件進行載入。
7.什麼是RPC
RPC全稱為remote procedure call,即遠端過程呼叫。比如兩臺伺服器A和B,A伺服器上部署一個應用,B伺服器上部署一個應用,A伺服器上的應用想呼叫B伺服器上的應用提供的方法,由於兩個應用不在一個記憶體空間,不能直接呼叫,所以需要通過網路來表達呼叫的語義和傳達呼叫的資料。
需要注意的是RPC並不是一個具體的技術,而是指整個網路遠端呼叫過程。
接的NIO框架抽象封裝,包括多種執行緒模型,序列化,以及“請求-響應”模式的資訊交換方式。
-
叢集容錯: 提供基於介面方法的透明遠端過程呼叫,包括多協議支援,以及軟負載均衡,失敗容錯,地址路由,動態配置等叢集支援。
-
自動發現: 基於註冊中心目錄服務,使服務消費方能動態的查詢服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
6.Dubbo能做什麼?
1.透明化的遠端方法呼叫,就像呼叫本地方法一樣呼叫遠端方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬體負載均衡器,降低成本,減少單點。
3.服務自動註冊與發現,不再需要寫死服務提供方地址,註冊中心基於介面名查詢服務提供者的IP地址,並且能夠平滑新增或刪除服務提供者。
Dubbo採用全spring配置方式,透明化接入應用,對應用沒有任何API侵入,只需用Spring載入Dubbo的配置即可,Dubbo基於Spring的Schema擴充套件進行載入。
7.什麼是RPC
RPC全稱為remote procedure call,即遠端過程呼叫。比如兩臺伺服器A和B,A伺服器上部署一個應用,B伺服器上部署一個應用,A伺服器上的應用想呼叫B伺服器上的應用提供的方法,由於兩個應用不在一個記憶體空間,不能直接呼叫,所以需要通過網路來表達呼叫的語義和傳達呼叫的資料。
需要注意的是RPC並不是一個具體的技術,而是指整個網路遠端呼叫過程。
RPC是一個泛化的概念,嚴格來說一切遠端過程呼叫手段都屬於RPC範疇。各種開發語言都有自己的RPC框架。Java中的RPC框架比較多,廣泛使用的有RMI、Hessian、Dubbo等。
相關文章
- Java入門基礎知識點Java
- Python入門必知的知識點!Python基礎入門Python
- JavaScript 基礎知識入門JavaScript
- MySql入門--基礎知識MySql
- css 入門基礎知識CSS
- JavaScript入門①-基礎知識築基JavaScript
- sql入門基礎知識分享SQL
- Java基礎知識入門-JDKJavaJDK
- Python基礎入門知識點——if 語句簡介Python
- Python基礎入門知識點——深淺拷貝Python
- Linux驅動入門基礎基礎知識Linux
- Python基礎知識入門(二)Python
- Python入門基礎知識(二)Python
- 【LaTeX入門】01、LaTeX基礎知識
- Dubbo入門(1) - 基礎概念
- OpenSSL 入門:密碼學基礎知識密碼學
- Python入門基礎知識例項,Python
- Python入門之基礎知識(一)Python
- WebSocket系列之基礎知識入門篇Web
- Python類的基礎入門知識Python
- Python基礎入門知識點——Python中的異常Python
- java基礎知識點Java
- JavaWeb基礎知識點JavaWeb
- JavaScript基礎知識點JavaScript
- Android NDK入門:C++ 基礎知識AndroidC++
- 爬蟲開發知識入門基礎(1)爬蟲
- Python 基礎(一):入門必備知識Python
- Python入門基礎知識學什麼?Python
- Python快速入門之基礎知識(一)Python
- Altium Designer 20 入門基礎知識(5)
- Altium Designer 20 入門基礎知識(1)
- oracle架構的基礎知識(入門級)Oracle架構
- [WebGL入門]五,矩陣的基礎知識Web矩陣
- React入門知識點整理React
- Canvas快速入門知識點Canvas
- Java基礎知識點梳理Java
- Servlet基礎知識點整理Servlet
- JavaScript部分基礎知識點JavaScript