網站建設資質百度app下載最新版本
SpringBoot-03
- (十四)、任務
- 1.異步任務
- 2.郵件任務
- (1).簡單郵箱發(fā)送
- (2).復雜郵箱發(fā)送
- 3.定時任務
- (1).cron表達式
- (2).特殊表達式
- (3).定時任務測試
- (4).常用cron表達式
- (十五)、Dubbo和Zookeeper集成
- 1.分布式原理
- (1).Dubbo文檔
- 2.什么是RPC?
- 3.Dubbo的概念和介紹
- (1).Dubbo是什么
- (2). Dubbo能做什么
- 3.搭建測試環(huán)境
- (1).Zookeeper介紹
- (2).window下安裝zookeeper
- (3).window下安裝dubbo-admin
- 4.SpringBoot + Dubbo + zookeeper
- (1).框架搭建
- (2).服務提供者 provider-server
- (3).服務消費者
(十四)、任務
1.異步任務
所謂異步,在某些功能實現(xiàn)時可能要花費一定的時間,但是為了不影響客戶端的體驗,選擇異步執(zhí)行執(zhí)行等待,前端直接展現(xiàn)。
在本列中我們設置線程等待事件為3秒,接著影響的是前端會轉圈三秒才能進入
service層
@Service
public class AsyncService {public void hello(){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("數(shù)據(jù)正在傳輸...");}
}
controller層
@RestController
public class AsyncController {@AutowiredAsyncService asyncService;@RequestMapping("/hello")public String async(){asyncService.hello();return "ok";}
}
這樣在執(zhí)行/hello請求時,網站會延時三秒再顯示ok,后臺數(shù)據(jù)也會三秒后顯示數(shù)據(jù)正在傳輸
現(xiàn)在想要做到前端快速響應我們的頁面,后臺去慢慢的傳輸數(shù)據(jù),就要用到springboot自帶的功能-----》 異步
①想辦法告訴spring我們的異步方法是異步的,所以要在方法上添加注解
package com.jsxs.service;import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;@Service
// 告訴Spring這是一個異步的方法
@Async
public class AsyncService {public void hello(){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("數(shù)據(jù)正在處理???");}
}
②去springboot主程序中開啟異步注解功能
package com.jsxs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication
// 開啟異步注解功能
@EnableAsync
public class SpringBoot09TestApplication {public static void main(String[] args) {SpringApplication.run(SpringBoot09TestApplication.class, args);}}
重啟即可
我么發(fā)現(xiàn)前端頁面會直接顯示,后端的等待事件進行異步等待
2.郵件任務
郵件發(fā)送,在我們的日常開發(fā)中,也非常的多,Springboot也幫我們做了支持
- 郵件發(fā)送需要引入spring-boot-start-mail
- SpringBoot 自動配置MailSenderAutoConfiguration
- 定義MailProperties內容,配置在a
- pplication.yml中
- 自動裝配JavaMailSender測試郵件發(fā)送
測試:
(1).簡單郵箱發(fā)送
1、引入pom依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
2、配置文件:
# 用戶名
spring.mail.username=2261203961@qq.com
# 授權碼
spring.mail.password=你的郵箱授權碼
# 鏈接主機
spring.mail.host=smtp.qq.com
# 開啟加密驗證
spring.mail.properties.mail.smtp.ssl.enable=true
首先你需要去郵箱網站開啟POP3/SMTP
3、Spring單元測試
package com.jsxs;import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;import javax.annotation.Resource;@SpringBootTest
class SpringBoot09TestApplicationTests {@ResourceJavaMailSenderImpl sender;@Testvoid contextLoads() {SimpleMailMessage message = new SimpleMailMessage();message.setSubject("2022吉林省軟件設計大賽"); // 主題message.setText("汪汪隊摸大魚榮獲三等獎"); // 文章內容message.setFrom("2261203961@qq.com"); // 發(fā)送人message.setTo("2261203961@qq.com");sender.send(message);System.out.println("發(fā)送成功");}}
(2).復雜郵箱發(fā)送
發(fā)送一個較為復雜的郵件:
@Testvoid contextLoads2() throws MessagingException {// 一個復雜的郵件MimeMessage message = sender.createMimeMessage();// 組裝MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(message,true);mimeMessageHelper.setSubject("2022吉林省軟件設計大賽");// htmlmimeMessageHelper.setText("<p style='color:red'>汪汪隊摸大魚榮獲三等獎</p>",true); // 添加true目的是為了能夠解析html// 附件 ----> 一定要復制絕對路徑mimeMessageHelper.addAttachment("1.jpg",new File("E:\\Ideal源碼\\SpringBoot-09-test\\src\\main\\resources\\static\\img\\1.jpg"));mimeMessageHelper.setFrom("2261203961@qq.com");mimeMessageHelper.setTo("2261203961@qq.com");sender.send(message);}
查看郵箱,郵件接收成功!
我們只需要使用Thymeleaf進行前后端結合即可開發(fā)自己網站郵件收發(fā)功能了!
要學會封裝成一個工具類,自己調用自己設置的接口就可以了
3.定時任務
項目開發(fā)中經常需要執(zhí)行一些定時任務,比如需要在每天凌晨的時候,分析一次前一天的日志信息,Spring為我們提供了異步執(zhí)行任務調度的方式,提供了兩個接口。
- TaskExecutor接口 -----》
任務調度者
- TaskScheduler接口 ------》
任務執(zhí)行者
兩個注解:
- @EnableScheduling ----- 》開啟定時的注解
- @Scheduled -----》什么時候執(zhí)行
(1).cron表達式
Cron表達式是一個具有時間含義的字符串,字符串以5-6個空格隔開,分為6~7個域,格式為X X X X X X X。其中X是一個域的占位符。最后一個代表年份的域非必須,可省略。單個域有多個取值時,使用半角逗號,隔開取值。每個域可以是確定的取值,也可以是具有邏輯意義的特殊字符。每個域最多支持一個前導零。
cron表達式格式:
{秒數(shù)} {分鐘} {小時} {日期} {月份} {星期} {年份(可為空)}
字段 | 允許值 | 允許的特殊字符 |
---|---|---|
秒(Seconds) | 0~59的整數(shù) | , - * / 四個字符 |
分(Minutes) | 0~59的整數(shù) | , - * / 四個字符 |
小時(Hours) | 0~23的整數(shù) | , - * / 四個字符 |
日期(DayofMonth) | 1~31的整數(shù)(但是你需要考慮你月的天數(shù) | ,- * ? / L W C 八個字符 |
月份(Month)) | 1~12的整數(shù)或者 JAN-DEC | , - * / 四個字符 |
星期(DayofWeek) | 1~7的整數(shù)或者 SUN-SAT (1=SUN) | , - * ? / L C # 八個字符 |
年(可選,留空)(Year) | 1970~2099 | , - * / 四個字符 |
(2).特殊表達式
Cron表達式中的每個域都支持一定數(shù)量的特殊字符,每個特殊字符有其特殊含義。
(3).定時任務測試
1、創(chuàng)建一個ScheduledService
我們里面存在一個hello方法,他需要定時執(zhí)行,怎么處理呢?
package com.jsxs.service;import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;@Service
public class ScheduledService {// 我們想要在一個特定的時間執(zhí)行這個方法~// cron 表達式--》 秒 分 時 日 月 周幾@Scheduled(cron = "0 39 18 * * 0-7")public void hello(){System.out.println("hello 被你執(zhí)行了");}
}
2、這里寫完定時任務之后,我們需要在主程序上增加@EnableScheduling 開啟定時任務功能
package com.jsxs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication
// 開啟異步功能的注解
@EnableAsync
// 開啟定時功能的注解
@EnableScheduling
public class SpringBoot09TestApplication {public static void main(String[] args) {SpringApplication.run(SpringBoot09TestApplication.class, args);}}
(4).常用cron表達式
(1)0 0 2 1 * ? * 表示在每月的1日的凌晨2點調整任務
(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15執(zhí)行作業(yè)
(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每個月的最后一個星期五上午10:15執(zhí)行
(4)0 0 10,14,16 * * ? 每天上午10點,下午2點,4
(5)0 0/30 9-17 * * ? 朝九晚五工作時間內每半小
(6)0 0 12 ? * WED 表示每個星期三中午12
(7)0 0 12 * * ? 每天中午12點觸
(8)0 15 10 ? * * 每天上午10:15觸
(9)0 15 10 * * ? 每天上午10:15觸
(10)0 15 10 * * ? * 每天上午10:15觸
(11)0 15 10 * * ? 2005 2005年的每天上午10:15觸
(12)0 * 14 * * ? 在每天下午2點到下午2:59期間的每1分鐘觸
(13)0 0/5 14 * * ? 在每天下午2點到下午2:55期間的每5分鐘觸
(14)0 0/5 14,18 * * ? 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸
(15)0 0-5 14 * * ? 在每天下午2點到下午2:05期間的每1分鐘觸
(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44觸發(fā)
(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15觸發(fā)
(18)0 15 10 15 * ? 每月15日上午10:15觸發(fā)
(19)0 15 10 L * ? 每月最后一日的上午10:15觸發(fā)
(20)0 15 10 ? * 6L 每月的最后一個星期五上午10:15觸發(fā)
(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一個星期五上午10:15觸發(fā)
(22)0 15 10 ? * 6 #3 每月的第三個星期五上午10:15觸發(fā)
(1)0/2 * * * * ? 表示每2秒 執(zhí)行任務
(1)0 0/2 * * * ? 表示每2分鐘 執(zhí)行任務
(1)0 0 2 1 * ? 表示在每月的1日的凌晨2點調整任務
(2)0 15 10 ? * MON-FRI 表示周一到周五每天上午10:15執(zhí)行作業(yè)
(3)0 15 10 ? 6L 2002-2006 表示2002-2006年的每個月的最后一個星期五上午10:15執(zhí)行作
(4)0 0 10,14,16 * * ? 每天上午10點,下午2點,4點
(5)0 0/30 9-17 * * ? 朝九晚五工作時間內每半小時
(6)0 0 12 ? * WED 表示每個星期三中午12點
(7)0 0 12 * * ? 每天中午12點觸發(fā)
(8)0 15 10 ? * * 每天上午10:15觸發(fā)
(9)0 15 10 * * ? 每天上午10:15觸發(fā)
(10)0 15 10 * * ? 每天上午10:15觸發(fā)
(11)0 15 10 * * ? 2005 2005年的每天上午10:15觸發(fā)
(12)0 * 14 * * ? 在每天下午2點到下午2:59期間的每1分鐘觸發(fā)
(13)0 0/5 14 * * ? 在每天下午2點到下午2:55期間的每5分鐘觸發(fā)
(14)0 0/5 14,18 * * ? 在每天下午2點到2:55期間和下午6點到6:55期間的每5分鐘觸發(fā)
(15)0 0-5 14 * * ? 在每天下午2點到下午2:05期間的每1分鐘觸發(fā)
(16)0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44觸發(fā)
(17)0 15 10 ? * MON-FRI 周一至周五的上午10:15觸發(fā)
(18)0 15 10 15 * ? 每月15日上午10:15觸發(fā)
(19)0 15 10 L * ? 每月最后一日的上午10:15觸發(fā)
(20)0 15 10 ? * 6L 每月的最后一個星期五上午10:15觸發(fā)
(21)0 15 10 ? * 6L 2002-2005 2002年至2005年的每月的最后一個星期五上午10:15觸發(fā)
(22)0 15 10 ? * 6#3 每月的第三個星期五上午10:15觸發(fā)
(十五)、Dubbo和Zookeeper集成
1.分布式原理
在《分布式系統(tǒng)原理與范型》一書中有如下定義:“分布式系統(tǒng)是若干獨立計算機的集合,這些計算機對于用戶來說就像單個相關系統(tǒng)
”;
? 分布式系統(tǒng)是由一組通過網絡進行通信、為了完成共同的任務而協(xié)調工作的計算機節(jié)點組成的系統(tǒng)。分布式系統(tǒng)的出現(xiàn)是為了用廉價的、普通的機器完成單個計算機無法完成的計算、存儲任務。其目的是利用更多的機器,處理更多的數(shù)據(jù)
。
? 分布式系統(tǒng)(distributed system)是建立在網絡之上的軟件系統(tǒng)。
? 首先需要明確的是,只有當單個節(jié)點的處理能力無法滿足日益增長的計算、存儲任務的時候,且硬件的提升(加內存、加磁盤、使用更好的CPU)高昂到得不償失的時候,應用程序也不能進一步優(yōu)化的時候,我們才需要考慮分布式系統(tǒng)
。(所以分布式不應該在一開始設計系統(tǒng)時就考慮到)因為,分布式系統(tǒng)要解決的問題本身就是和單機系統(tǒng)一樣的,而由于分布式系統(tǒng)多節(jié)點、通過網絡通信的拓撲結構,會引入很多單機系統(tǒng)沒有的問題,為了解決這些問題又會引入更多的機制、協(xié)議,帶來更多的問題。。。
(1).Dubbo文檔
隨著互聯(lián)網的發(fā)展,網站應用的規(guī)模不斷擴大,常規(guī)的垂直應用架構已無法應對,分布式服務架構以及流動計算架構勢在必行,急需一個治理系統(tǒng)確保架構有條不紊的演進
。
在Dubbo的官網文檔有這樣一張圖
隨著互聯(lián)網的發(fā)展,網站應用的規(guī)模不斷擴大,常規(guī)的垂直應用架構已無法應對,分布式服務架構以及流動計算架構勢在必行,亟需一個治理系統(tǒng)確保架構有條不紊的演進。
單一應用架構
當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節(jié)點和成本。此時,用于簡化增刪改查工作量的數(shù)據(jù)訪問框架(ORM)是關鍵。
垂直應用架構
當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,提升效率的方法之一是將應用拆成互不相干的幾個應用,以提升效率。此時,用于加速前端頁面開發(fā)的Web框架(MVC)是關鍵。
缺點:公用模塊無法重復利用,開發(fā)性的浪費
分布式服務架構
當垂直應用越來越多,應用之間交互不可避免,將核心業(yè)務抽取出來,作為獨立的服務,逐漸形成穩(wěn)定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,用于提高業(yè)務復用及整合的分布式服務框架(RPC)是關鍵。
流動計算架構
當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現(xiàn),此時需增加一個調度中心基于訪問壓力實時管理集群容量,提高集群利用率。此時,用于提高機器利用率的資源調度和治理中心(SOA)是關鍵。
2.什么是RPC?
RPC【Remote Procedure Call】是指遠程過程調用
,是一種進程間通信方式,他是一種技術的思想,而不是規(guī)范。它允許程序調用另一個地址空間(通常是共享網絡的另一臺機器上)的過程或函數(shù),而不用程序員顯式編碼這個遠程調用的細節(jié)。即程序員無論是調用本地的還是遠程的函數(shù),本質上編寫的調用代碼基本相同。
也就是說兩臺服務器A,B,一個應用部署在A服務器上,想要調用B服務器上應用提供的函數(shù)/方法,由于不在一個內存空間,不能直接調用,需要通過網絡來表達調用的語義和傳達調用的數(shù)據(jù)。為什么要用RPC呢?就是無法在一個進程內,甚至一個計算機內通過本地調用的方式完成的需求,比如不同的系統(tǒng)間的通訊,甚至不同的組織間的通訊,由于計算能力需要橫向擴展,需要在多臺機器組成的集群上部署應用。RPC就是要像調用本地的函數(shù)一樣去調遠程函數(shù);
推薦閱讀文章:https://www.jianshu.com/p/2accc2840a1b
說白了就是不同于調用本地的而是調用遠程資源和方法
RPC原理:
步驟分析:
RPC兩個核心模塊:通訊(信息傳送),序列化(數(shù)據(jù)傳輸需要轉換)。
3.Dubbo的概念和介紹
(1).Dubbo是什么
Dubbo是一個分布式服務框架,致力于提供高性能和透明化的RPC遠程服務調用方案,以及SOA服務治理方案。簡單的說,dubbo就是個服務框架,如果沒有分布式的需求,其實是不需要用的,只有在分布式的時候,才有dubbo這樣的分布式服務框架的需求,并且本質上是個服務調用的東東,說白了就是個遠程服務調用的分布式框架
其核心部分包含:
1》遠程通訊: 提供對多種基于長連接的NIO框架抽象封裝,包括多種線程模型,序列化,以及“請求-響應”模式的信息交換方式。
2》集群容錯: 提供基于接口方法的透明遠程過程調用,包括多協(xié)議支持,以及軟負載均衡,失敗容錯,地址路由,動態(tài)配置等集群支持。
3》自動發(fā)現(xiàn): 基于注冊中心目錄服務,使服務消費方能動態(tài)的查找服務提供方,使地址透明,使服務提供方可以平滑增加或減少機器。
(2). Dubbo能做什么
1.透明化的遠程方法調用,就像調用本地方法一樣調用遠程方法,只需簡單配置,沒有任何API侵入。
2.軟負載均衡及容錯機制,可在內網替代F5等硬件負載均衡器,降低成本,減少單點。
3.服務自動注冊與發(fā)現(xiàn),不再需要寫死服務提供方地址,注冊中心基于接口名查詢服務提供者的IP地址,并且能夠平滑添加或刪除服務提供者。
3.搭建測試環(huán)境
Apache Dubbo |?d?b??| 是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動注冊和發(fā)現(xiàn)。
服務提供者(Provider):暴露服務的服務提供方,服務提供者在啟動時,向注冊中心注冊自己提供的服務。
服務消費者(Consumer):調用遠程服務的服務消費方,服務消費者在啟動時,向注冊中心訂閱自己所需的服務,服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
注冊中心(Registry):注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數(shù)據(jù)給消費者
監(jiān)控中心(Monitor):服務消費者和提供者,在內存中累計調用次數(shù)和調用時間,定時每分鐘發(fā)送一次統(tǒng)計數(shù)據(jù)到監(jiān)控中心
調用關系說明
l 服務容器負責啟動,加載,運行服務提供者。
l 服務提供者在啟動時,向注冊中心注冊自己提供的服務。
l 服務消費者在啟動時,向注冊中心訂閱自己所需的服務。
l 注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數(shù)據(jù)給消費者。
l 服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。
l 服務消費者和提供者,在內存中累計調用次數(shù)和調用時間,定時每分鐘發(fā)送一次統(tǒng)計數(shù)據(jù)到監(jiān)控中心
(1).Zookeeper介紹
Zoookeeper是什么?
官方文檔上這么解釋zookeeper,它是一個分布式服務框架,是Apache Hadoop 的一個子項目,它主要是用來解決分布式應用中經常遇到的一些數(shù)據(jù)管理問題,如:統(tǒng)一命名服務、狀態(tài)同步服務、集群管理、分布式應用配置項的管理等。
上面的解釋有點抽象,簡單來說zookeeper=文件系統(tǒng)+監(jiān)聽通知機制
。
①.文件系統(tǒng)
Zookeeper維護一個類似文件系統(tǒng)的數(shù)據(jù)結構
每個子目錄項如 NameService 都被稱作為 znode(目錄節(jié)點),和文件系統(tǒng)一樣,我們能夠自由的增加、刪除znode,在一個znode下增加、刪除子znode,唯一的不同在于znode是可以存儲數(shù)據(jù)的。
有四種類型的znode:
- PERSISTENT-持久化目錄節(jié)點客戶端與zookeeper斷開連接后,該節(jié)點依舊存在
- PERSISTENT_SEQUENTIAL-持久化順序編號目錄節(jié)點客戶端與zookeeper斷開連接后,該節(jié)點依舊存在,只是Zookeeper給該節(jié)點名稱進行順序編號
- EPHEMERAL-臨時目錄節(jié)點-客戶端與zookeeper斷開連接后,該節(jié)點被刪除
- EPHEMERAL_SEQUENTIAL-臨時順序編號目錄節(jié)點客戶端與zookeeper斷開連接后,該節(jié)點被刪除,只是Zookeeper給該節(jié)點名稱進行順序編號
②、 監(jiān)聽通知機制
客戶端注冊監(jiān)聽它關心的目錄節(jié)點,當目錄節(jié)點發(fā)生變化(數(shù)據(jù)改變、被刪除、子目錄節(jié)點增加刪除)時,zookeeper會通知客戶端。
就這么簡單,下面我們看看Zookeeper能做點什么呢?
Zookeeper能做什么?
zookeeper功能非常強大,可以實現(xiàn)諸如分布式應用配置管理、統(tǒng)一命名服務、狀態(tài)同步服務、集群管理等功能,我們這里拿比較簡單的分布式應用配置管理為例來說明。
假設我們的程序是分布式部署在多臺機器上,如果我們要改變程序的配置文件,需要逐臺機器去修改,非常麻煩,現(xiàn)在把這些配置全部放到zookeeper上去,保存在 zookeeper 的某個目錄節(jié)點中,然后所有相關應用程序對這個目錄節(jié)點進行監(jiān)聽,一旦配置信息發(fā)生變化,每個應用程序就會收到 zookeeper 的通知,然后從 zookeeper 獲取新的配置信息應用到系統(tǒng)中。
如上,你大致應該了解zookeeper是個什么東西,大概能做些什么了,我們馬上來學習下zookeeper的安裝及使用
(2).window下安裝zookeeper
1、下載zookeeper :地址, 我們下載3.4.14 , 最新版!解壓zookeeper
2、運行/bin/zkServer.cmd ,初次運行會報錯,沒有zoo.cfg配置文件;
安裝包地址:鏈接:https://pan.baidu.com/s/1_iRikIPD7J115f8r8uTLKg 提取碼:xd91
可能遇到問題:閃退 !
解決方案:編輯zkServer.cmd文件末尾添加pause 。這樣運行出錯就不會退出,會提示錯誤信息,方便找到原因。
3、修改zoo.cfg配置文件
將conf文件夾下面的zoo_sample.cfg復制一份改名為zoo.cfg即可。
注意幾個重要位置:
dataDir=./ 臨時數(shù)據(jù)存儲的目錄(可寫相對路徑)
clientPort=2181 zookeeper的端口號
修改完成后再次啟動zookeeper
4、使用zkCli.cmd測試
ls /:列出zookeeper根下保存的所有節(jié)點
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
create –e /jsxs 12:創(chuàng)建一個jsxs節(jié)點,值為12
[zk: localhost:2181(CONNECTED) 10] create -e /jsxs 12
Created /jsxs
我們再來查看一下節(jié)點
get /jsxs
12
cZxid = 0x6
ctime = Thu Feb 09 12:17:02 GMT+08:00 2023
mZxid = 0x6
mtime = Thu Feb 09 12:17:02 GMT+08:00 2023
pZxid = 0x6
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x1000db767b10000
dataLength = 2
numChildren = 0
(3).window下安裝dubbo-admin
dubbo本身并不是一個服務軟件。它其實就是一個jar包,能夠幫你的java程序連接到zookeeper,并利用zookeeper消費、提供服務。
但是為了讓用戶更好的管理監(jiān)控眾多的dubbo服務,官方提供了一個可視化的監(jiān)控程序dubbo-admin
,不過這個監(jiān)控即使不裝也不影響使用。
我們這里來安裝一下:
1、下載dubbo-admin
地址 :https://github.com/apache/dubbo-admin/tree/master
2、解壓進入目錄
解壓后,進入dubbo-admin-master,
首先,要進入dubbo-admin-master\dubbo-admin-server\src\main\resources中的application.properties目錄下,指定zookeeper的地址:
server.port=7001
spring.velocity.cache=false
spring.velocity.charset=UTF-8
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
spring.messages.basename=i18n/message
spring.root.password=root
spring.guest.password=guestdubbo.registry.address=zookeeper://127.0.0.1:2181
3、在項目目錄下打包dubbo-admin
e:
cd Dubbo-admin\dubbo-admin-master-0.2.0\dubbo-admin-master-0.2.0
mvn clean package -Dmaven.test.skip=true
第一次打包的過程有點慢,需要耐心等待!直到成功!
4、執(zhí)行 dubbo-admin\target 下的dubbo-admin-0.0.1-SNAPSHOT.jar
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
【注意:zookeeper的服務一定要打開!】
執(zhí)行完畢,我們去訪問一下 http://localhost:7001/ , 這時候我們需要輸入登錄賬戶和密碼,我們都是默認的root-root;
登錄成功后,查看界面
4.SpringBoot + Dubbo + zookeeper
(1).框架搭建
1 啟動zookeeper !
2 IDEA創(chuàng)建一個空項目;
3.創(chuàng)建一個模塊,實現(xiàn)服務提供者:provider-server , 選擇web依賴即可
4.項目創(chuàng)建完畢,我們寫一個服務,比如賣票的服務;
編寫接口
package com.jsxs.provider.service;public interface TicketService {public String getTicket();
}
編寫實現(xiàn)類
package com.jsxs.service;public class TicketServiceImpl implements TicketService{@Overridepublic String getTicket() {return "JSXS";}
}
5.創(chuàng)建一個模塊,實現(xiàn)服務消費者:consumer-server , 選擇web依賴即可
6.項目創(chuàng)建完畢,我們寫一個服務,比如用戶的服務;
編寫service
package com.jsxs.service;public interface UserService {// 想獲取provider-server提供的票}
需求:現(xiàn)在我們的用戶想使用買票的服務,這要怎么弄呢 ?
(2).服務提供者 provider-server
1、將服務提供者注冊到注冊中心,我們需要整合Dubbo和zookeeper,所以需要導包
我們從dubbo官網進入github,看下方的幫助文檔,找到dubbo-springboot,找到依賴包
<!-- Dubbo Spring Boot Starter -->
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.3</version>
</dependency>
zookeeper的包我們去maven倉庫下載,zkclient;
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version>
</dependency>
【新版的坑】zookeeper及其依賴包,解決日志沖突,還需要剔除日志依賴;
<!-- 引入zookeeper -->
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.12.0</version>
</dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.12.0</version>
</dependency>
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.14</version><!--排除這個slf4j-log4j12--><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions>
</dependency>
2、在springboot配置文件中配置dubbo相關屬性!
# 售票服務端口 8081 用戶端口 8082
server.port=8081
#當前應用名字
dubbo.application.name=provider-server
#注冊中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#掃描指定包下服務
dubbo.scan.base-packages=com.jsxs.service
3、在service的實現(xiàn)類中配置服務注解,發(fā)布服務!注意導包問題,因為這里的Service注解需要導入的是dubbo中的注解,而不是spring的注解,所以要把其注入就要用Componet,不過最新版本的好像已經解決這個問題:一個新的注解@DubboService
package com.jsxs.service;import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;@Service //將服務發(fā)布出去 org.apache.dubbo.config.annotation.Service
@Component //放在容器中
public class TicketServiceImpl implements TicketService{@Overridepublic String getTicket() {return "JSXS";}
}
邏輯理解 :應用啟動起來,dubbo就會掃描指定的包下帶有@component注解的服務,將它發(fā)布在指定的注冊中心中!
開啟服務
>
鏈接服務
開啟視圖
查看視圖
查看數(shù)據(jù)
(3).服務消費者
1.導入依賴,和之前的依賴一樣;
<!--dubbo-->
<!-- Dubbo Spring Boot Starter -->
<dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.3</version>
</dependency>
<!--zookeeper-->
<!-- https://mvnrepository.com/artifact/com.github.sgroschupf/zkclient -->
<dependency><groupId>com.github.sgroschupf</groupId><artifactId>zkclient</artifactId><version>0.1</version>
</dependency>
<!-- 引入zookeeper -->
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>2.12.0</version>
</dependency>
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>2.12.0</version>
</dependency>
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.4.14</version><!--排除這個slf4j-log4j12--><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions>
</dependency>
2.配置參數(shù)
# 售票服務端口 8081 用戶端口 8082
server.port=8082# 消費者去哪里拿?#當前應用名字
dubbo.application.name=consumer-server
#注冊中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
3.本來正常步驟是需要將服務提供者的接口打包,然后用pom文件導入,我們這里使用簡單的方式,直接將服務的接口拿過來,路徑必須保證正確,即和服務提供者相同;
4.完善消費者的服務類
package com.jsxs.service;import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;@Service //注入到容器中 springframework.stereotype.Service;
public class UserService {// 想獲取provider-server提供的票,要去注冊中心拿@Reference //遠程引用指定的服務,他會按照全類名進行匹配,看誰給注冊中心注冊了這個全類名TicketService ticketService;public void buyTicket() {String ticket = ticketService.getTicket();System.out.println("在注冊中心買到" + ticket);}}
5.測試類編寫
package com.jsxs;import com.jsxs.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;@SpringBootTest
class ConsumerServerApplicationTests {@ResourceUserService userService;@Testvoid contextLoads() {userService.buyTicket();}}
微服務架構問題:
分布式架構會遇到的四個核心問題:
1.這么多的服務,客戶端該如何去訪問?
2.這么多的服務,服務器之間如何進行通信?
3.這么多的服務,該如何管理和治理?
4.服務掛了,怎么辦?
解決方案:
SpringCloud,是一套生態(tài),就是來解決以上分布式架構的四個問題
想使用SpringCloud,必須要掌握Springboot,因為它是基于SpirngBoot的
1.SpringCloud NetFlix,出了一套解決方案
2.Apcahe Dubbo zookeeper 第二套解決方案
API:沒有,要么找第三方,要么自己實現(xiàn)
Dubbo是一個高性能的基于java實現(xiàn)的RPC通信框架
服務注冊與發(fā)現(xiàn),zookeeper,沒有熔斷機制,接住了Hystrix
3.SpringCloud Alibaba 一站式解決方案!