新聞中心
硬編碼的問(wèn)題
(1)如果用戶微服務(wù)和商品微服務(wù)的IP地址或者端口號(hào)發(fā)生了變化,則訂單微服務(wù)將變得不可用,需要對(duì)同步修改訂單微服務(wù)中調(diào)用用戶微服務(wù)和商品微服務(wù)的IP地址和端口號(hào)。

雨花網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,雨花網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為雨花上千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的雨花做網(wǎng)站的公司定做!
(2)如果系統(tǒng)中提供了多個(gè)用戶微服務(wù)和商品微服務(wù),則無(wú)法實(shí)現(xiàn)微服務(wù)的負(fù)載均衡功能。
(3)如果系統(tǒng)需要支持更高的并發(fā),需要部署更多的用戶微服務(wù)和商品微服務(wù)以及訂單微服務(wù),如果將用戶微服務(wù)和商品微服務(wù)的IP地址和端口硬編碼到訂單微服務(wù),則后續(xù)的維護(hù)會(huì)變得異常復(fù)雜。
所以,在微服務(wù)開發(fā)的過(guò)程中,需要引入服務(wù)治理功能,實(shí)現(xiàn)微服務(wù)之間的動(dòng)態(tài)注冊(cè)與發(fā)現(xiàn)。
服務(wù)治理
如果系統(tǒng)采用了微服務(wù)的架構(gòu)模式,隨著微服務(wù)數(shù)量的不斷增多,服務(wù)之間的調(diào)用關(guān)系會(huì)變得縱橫交錯(cuò),以純?nèi)斯な謩?dòng)的方式來(lái)管理這些微服務(wù)以及微服務(wù)之間的調(diào)用關(guān)系是及其復(fù)雜的,也是極度不可取的。
所以,需要引入服務(wù)治理的功能。服務(wù)治理也是在微服務(wù)架構(gòu)模式下的一種最核心和最基本的模塊,主要用來(lái)實(shí)現(xiàn)各個(gè)微服務(wù)的自動(dòng)注冊(cè)與發(fā)現(xiàn)。
引入服務(wù)治理后,微服務(wù)項(xiàng)目總體上可以分為三個(gè)大的模塊:服務(wù)提供者、服務(wù)消費(fèi)者和注冊(cè)中心,三者的關(guān)系如下圖所示。
(1)服務(wù)提供者會(huì)將自身提供的服務(wù)注冊(cè)到注冊(cè)中心,并向注冊(cè)中心發(fā)送心跳信息來(lái)證明自己還存活,其中,心跳信息中就會(huì)包含服務(wù)提供者自身提供的服務(wù)信息。
(2)注冊(cè)中心會(huì)存儲(chǔ)服務(wù)提供者上報(bào)的信息,并通過(guò)服務(wù)提供者發(fā)送的心跳來(lái)更新服務(wù)提供者最后的存活時(shí)間,如果超過(guò)一段時(shí)間沒(méi)有收到服務(wù)提供者上報(bào)的心跳信息,則注冊(cè)中心會(huì)認(rèn)為服務(wù)提供者不可用,會(huì)將對(duì)應(yīng)的服務(wù)提供者從服務(wù)列表中剔除。
(3)服務(wù)消費(fèi)者會(huì)向注冊(cè)中心訂閱自身監(jiān)聽(tīng)的服務(wù),注冊(cè)中心會(huì)保存服務(wù)消費(fèi)者的信息,也會(huì)向服務(wù)消費(fèi)者推送服務(wù)提供者的信息。
(4)服務(wù)消費(fèi)者從注冊(cè)中心獲取到服務(wù)提供者的信息時(shí),會(huì)直接調(diào)用服務(wù)提供者的接口來(lái)實(shí)現(xiàn)遠(yuǎn)程調(diào)用。
這里需要注意的是:服務(wù)消費(fèi)者一般會(huì)從注冊(cè)中心中獲取到所有服務(wù)提供者的信息,根據(jù)具體情況實(shí)現(xiàn)對(duì)具體服務(wù)提供者的實(shí)例進(jìn)行訪問(wèn)。
注冊(cè)中心
從上面的分析可以看出,微服務(wù)實(shí)現(xiàn)服務(wù)治理的關(guān)鍵就是引入了注冊(cè)中心,它是微服務(wù)架構(gòu)模式下一個(gè)非常重要的組件,主要實(shí)現(xiàn)了服務(wù)注冊(cè)與發(fā)現(xiàn),服務(wù)配置和服務(wù)的健康檢測(cè)等功能。
服務(wù)注冊(cè)與發(fā)現(xiàn)
(1)服務(wù)注冊(cè):注冊(cè)中心提供保存服務(wù)提供者和服務(wù)消費(fèi)者的相關(guān)信息。
(2)服務(wù)發(fā)現(xiàn):也可以理解為服務(wù)訂閱,服務(wù)調(diào)用者也就是服務(wù)消費(fèi)者,向注冊(cè)中心訂閱服務(wù)提供者的信息,注冊(cè)中心會(huì)向服務(wù)消費(fèi)者推送服務(wù)提供者的信息。
服務(wù)配置
(1)配置訂閱:服務(wù)的提供者和消費(fèi)者都可以向注冊(cè)中心訂閱微服務(wù)相關(guān)的配置信息。
(2)配置下發(fā):注冊(cè)中心能夠?qū)⑽⒎?wù)相關(guān)的配置信息主動(dòng)推送給服務(wù)的提供者和消費(fèi)者。
服務(wù)健康檢測(cè)
注冊(cè)中心會(huì)定期檢測(cè)存儲(chǔ)的服務(wù)列表中服務(wù)提供者的健康狀況,例如服務(wù)提供者超過(guò)一定的時(shí)間沒(méi)有上報(bào)心跳信息,則注冊(cè)中心會(huì)認(rèn)為對(duì)應(yīng)的服務(wù)提供者不可用,就會(huì)將服務(wù)提供者踢出服務(wù)列表。
常見(jiàn)的注冊(cè)中心
能夠?qū)崿F(xiàn)注冊(cè)中心功能的組件有很多,但是常用的組件大概包含:Zookeeper、Eureka、Consul、Etcd、Nacos等。這里,就給大家簡(jiǎn)單介紹下這些能夠?qū)崿F(xiàn)注冊(cè)中心功能的框架或組件。
(1)Zookeeper
接觸過(guò)分布式或者大數(shù)據(jù)開發(fā)的小伙伴應(yīng)該都知道,Zookeeper是Apache Hadoop的一個(gè)子項(xiàng)目,它是一個(gè)分布式服務(wù)治理框架,主要用來(lái)解決應(yīng)用開發(fā)中遇到的一些數(shù)據(jù)管理問(wèn)題,例如:分布式集群管理、元數(shù)據(jù)管理、分布式配置管理、狀態(tài)同步和統(tǒng)一命名管理等。在高并發(fā)環(huán)境下,也可以通過(guò)Zookeeper實(shí)現(xiàn)分布式鎖功能。
(2)Eureka
Eureka是Netflix開源的SpringCloud中支持服務(wù)注冊(cè)與發(fā)現(xiàn)的組件,但是后來(lái)閉源了。
(3)Consul
Consul 是 HashiCorp 公司推出的開源產(chǎn)品,用于實(shí)現(xiàn)分布式系統(tǒng)的服務(wù)發(fā)現(xiàn)、服務(wù)隔離、服務(wù)配置,這些功能中的每一個(gè)都可以根據(jù)需要單獨(dú)使用,也可以同時(shí)使用所有功能。
(4)Etcd
etcd 是一個(gè)高度一致的分布式鍵值存儲(chǔ),它提供了一種可靠的方式來(lái)存儲(chǔ)需要由分布式系統(tǒng)或機(jī)器集群訪問(wèn)的數(shù)據(jù)。它可以優(yōu)雅地處理網(wǎng)絡(luò)分區(qū)期間的領(lǐng)導(dǎo)者選舉,即使在領(lǐng)導(dǎo)者節(jié)點(diǎn)中也可以容忍機(jī)器故障。
(5)Nacos
這里,我們重點(diǎn)說(shuō)下Nacos。Nacos是阿里巴巴開源的一款更易于構(gòu)建云原生應(yīng)用的支持動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置管理和服務(wù)管理的平臺(tái),其提供了一組簡(jiǎn)單易用的特性集,能夠快速實(shí)現(xiàn)動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、服務(wù)配置、服務(wù)元數(shù)據(jù)及流量管理,主要如下所示。
- 服務(wù)注冊(cè):Nacos Client會(huì)通過(guò)發(fā)送REST請(qǐng)求的方式向Nacos Server注冊(cè)自己的服務(wù),提供自身的元數(shù)據(jù),比如IP地址、端口等信 息。Nacos Server接收到注冊(cè)請(qǐng)求后,就會(huì)把這些元數(shù)據(jù)信息存儲(chǔ)在一個(gè)雙層的內(nèi)存Map中。
- 服務(wù)心跳:在服務(wù)注冊(cè)后,Nacos Client會(huì)維護(hù)一個(gè)定時(shí)心跳來(lái)持續(xù)通知Nacos Server,說(shuō)明服務(wù)一直處于可用狀態(tài),防止被剔除。默認(rèn)5s發(fā)送一次心跳。
- 服務(wù)健康檢查:Nacos Server會(huì)開啟一個(gè)定時(shí)任務(wù)用來(lái)檢查注冊(cè)服務(wù)實(shí)例的健康情況,對(duì)于超過(guò)15s沒(méi)有收到客戶端心跳的實(shí)例會(huì)將它的healthy屬性置為false(客戶端服務(wù)發(fā)現(xiàn)時(shí)不會(huì)發(fā)現(xiàn)),如果某個(gè)實(shí)例超過(guò)30秒沒(méi)有收到心跳,直接剔除該實(shí)例(被剔除的實(shí)例如果恢復(fù)發(fā)送心跳則會(huì)重新注冊(cè))
- 服務(wù)發(fā)現(xiàn):服務(wù)消費(fèi)者(Nacos Client)在調(diào)用服務(wù)提供者的服務(wù)時(shí),會(huì)發(fā)送一個(gè)REST請(qǐng)求給Nacos Server,獲取上面注冊(cè)的服務(wù)清 單,并且緩存在Nacos Client本地,同時(shí)會(huì)在Nacos Client本地開啟一個(gè)定時(shí)任務(wù)定時(shí)拉取服務(wù)端最新的注冊(cè)表信息更新到本地存。
- 服務(wù)同步:Nacos Server集群之間會(huì)互相同步服務(wù)實(shí)例,用來(lái)保證服務(wù)信息的一致性。
這里,我們選用的注冊(cè)中心就是阿里巴巴開源的Nacos。
搭建Nacos環(huán)境
(1)到鏈接
https://github.com/alibaba/nacos/releases 下載Nacos的安裝包,我這里下載的安裝包為:nacos-server-1.4.3.zip。
(2)解壓Nacos安裝包,并在命令行進(jìn)入到Nacos的bin目錄下執(zhí)行如下命令以單機(jī)的方式啟動(dòng)Nacos。
startup.cmd -m standalone
注意:如果需要以單機(jī)的方式啟動(dòng)Nacos,則需要添加 -m standalone 參數(shù),否則,Nacos會(huì)以集群的方式啟動(dòng)。
(3)啟動(dòng)Nacos之后,在瀏覽器中輸入鏈接http://localhost:8848/nacos 來(lái)訪問(wèn)Nacos的管理界面,默認(rèn)的用戶名和密碼都是Nacos,如下所示。
輸入用戶名和密碼進(jìn)入Nacos的管理界面,如下所示。
這里,我們進(jìn)入到Nacos的服務(wù)管理-服務(wù)列表菜單下,如下所示。
可以看到,在Nacos的服務(wù)管理-服務(wù)列表菜單下還沒(méi)有任何服務(wù),接下來(lái),我們就對(duì)項(xiàng)目的代碼進(jìn)行改造。
集成Nacos注冊(cè)中心
引入Nacos注冊(cè)中心時(shí),我們需要對(duì)項(xiàng)目的代碼進(jìn)行一定的改造,以便利用Nacos實(shí)現(xiàn)服務(wù)的注冊(cè)與發(fā)現(xiàn)功能。
改造用戶微服務(wù)
(1)在用戶微服務(wù)的pom.xml文件中添加nacos的服務(wù)注冊(cè)與發(fā)現(xiàn)依賴,如下所示。
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
(2)在用戶微服務(wù)的resources目錄下的application.yml文件中添加Nacos注冊(cè)中心的服務(wù)地址配置,如下所示。
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
(3)在用戶微服務(wù)的啟動(dòng)類io.binghe.shop#UserStarter上標(biāo)注@EnableDiscoveryClient注解,如下所示。
/**
* @author binghe
* @version 1.0.0
* @description 啟動(dòng)用戶服的類
*/
@SpringBootApplication
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan(value = { "io.binghe.shop.user.mapper" })
@EnableDiscoveryClient
public class UserStarter {
public static void main(String[] args){
SpringApplication.run(UserStarter.class, args);
}
}
此時(shí),就完成了對(duì)用戶微服務(wù)的代碼改造。
(4)啟動(dòng)用戶微服務(wù),并刷新Nacos頁(yè)面,如下所示。
可以看到,用戶微服務(wù)已經(jīng)成功注冊(cè)到Nacos中。
改造其他微服務(wù)
我們可以用同樣的方式來(lái)改造商品微服務(wù)和訂單微服務(wù)的代碼,改造好之后,分別啟動(dòng)商品微服務(wù)和訂單微服務(wù),并再次刷新Nacos的頁(yè)面,如下所示。
可以看到,用戶微服務(wù)、商品微服務(wù)和訂單微服務(wù)都已成功注冊(cè)到Nacos。
實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)
按照整個(gè)項(xiàng)目的執(zhí)行流程,用戶執(zhí)行下單操作時(shí),訂單微服務(wù)會(huì)調(diào)用用戶微服務(wù)的接口獲取用戶的基本信息,會(huì)調(diào)用商品微服務(wù)的接口獲取商品的基本信息。
在訂單微服務(wù)中校驗(yàn)用戶的合法性和校驗(yàn)商品庫(kù)存是否充足,如果用戶合法并且商品庫(kù)存充足,就會(huì)向訂單數(shù)據(jù)表中記錄訂單信息并調(diào)用商品微服務(wù)的接口來(lái)扣減商品的庫(kù)存。
用戶微服務(wù)和商品微服務(wù)作為服務(wù)的提供者,而訂單微服務(wù)作為服務(wù)的消費(fèi)者,如果要實(shí)現(xiàn)服務(wù)的發(fā)現(xiàn)功能,我們還需要對(duì)訂單微服務(wù)的代碼進(jìn)行改造。將訂單微服務(wù)中硬編碼的用戶微服務(wù)和商品微服務(wù)的IP地址和端口號(hào)修改成從Nacos中獲取。
為了讓小伙伴們能夠更好的對(duì)比修改前和修改后的代碼,這里,并沒(méi)有在訂單微服務(wù)的 io.binghe.shop.order.service.impl#OrderServiceImpl 類上直接修改,還是將其重命名為 io.binghe.shop.order.service.impl.OrderServiceV1Impl 類,同時(shí),再次將其復(fù)制一份并命名為io.binghe.shop.order.service.impl.OrderServiceV2Impl類,在后續(xù)的開發(fā)過(guò)程中,如果涉及到大的代碼變動(dòng),都會(huì)以這種方式進(jìn)行更新。
注入服務(wù)發(fā)現(xiàn)類
(1)在io.binghe.shop.order.service.impl.OrderServiceV2Impl 類中首先注入DiscoveryClient類的對(duì)象,如下所示。
@Autowired
private DiscoveryClient discoveryClient;
創(chuàng)建動(dòng)態(tài)服務(wù)地址方法
在io.binghe.shop.order.service.impl.OrderServiceV2Impl 類中創(chuàng)建一個(gè)從Nacos中通過(guò)服務(wù)名稱獲取IP和端口號(hào)的方法getServiceUrl(),并在getServiceUrl()方法中將IP和端口號(hào)拼接成IP:PORT的形式,如下所示。
private String getServiceUrl(String serviceName){
ServiceInstance serviceInstance = discoveryClient.getInstances(serviceName).get(0);
return serviceInstance.getHost() + ":" + serviceInstance.getPort();
}具體的實(shí)現(xiàn)方式就是調(diào)用DiscoveryClient對(duì)象的getInstances()方法,并傳入服務(wù)的名稱,從Nacos注冊(cè)中心中獲取一個(gè)ServiceInstance類型的List集合,從List集合中獲取第1個(gè)元素,也就是從List集合中獲取到一個(gè)ServiceInstance對(duì)象,從ServiceInstance對(duì)象中獲取到IP地址和端口號(hào),并將其拼接成IP:PORT的形式。
定義服務(wù)提供者名稱
在io.binghe.shop.order.service.impl.OrderServiceV2Impl 類中定義兩個(gè)成員變量userServer和productServer,表示用戶微服務(wù)和商品微服務(wù)的服務(wù)名稱,并將其分別復(fù)制為server-user和server-product。
private String userServer = "server-user";
private String productServer = "server-product";
注意:userServer的值需要與用戶微服務(wù)下的application.yml文件中的如下配置的值相同。
spring:
application:
name: server-user
productServer的值需要與商品微服務(wù)下的application.yml文件中的如下配置的值相同。
spring:
application:
name: server-product
修改提交訂單邏輯
在io.binghe.shop.order.service.impl.OrderServiceV2Impl 類的saveOrder()方法中,將硬編碼的用戶微服務(wù)和商品微服務(wù)的IP和端口修改成從Nacos注冊(cè)中心中獲取,涉及改動(dòng)的代碼片段如下所示。
(1)添加獲取用戶微服務(wù)與商品微服務(wù)的IP和端口號(hào)的代碼片段,如下所示。
//從Nacos服務(wù)中獲取用戶服務(wù)與商品服務(wù)的地址
String userUrl = this.getServiceUrl(userServer);
String productUrl = this.getServiceUrl(productServer);
(2)修改使用restTemplate獲取用戶信息的代碼片段,修改前的代碼片段如下所示。
User user = restTemplate.getForObject("http://localhost:8060/user/get/" + orderParams.getUserId(), User.class);
if (user == null){
throw new RuntimeException("未獲取到用戶信息: " + JSONObject.toJSONString(orderParams));
}修改后的代碼片段如下所示。
User user = restTemplate.getForObject("http://" + userUrl + "/user/get/" + orderParams.getUserId(), User.class);
if (user == null){
throw new RuntimeException("未獲取到用戶信息: " + JSONObject.toJSONString(orderParams));
}可以看到,訂單微服務(wù)獲取用戶微服務(wù)信息時(shí),不再是硬編碼用戶微服務(wù)的IP地址和端口號(hào)了。
(3)修改使用restTemplate獲取商品信息的代碼片段,修改前的代碼片段如下所示。
Product product = restTemplate.getForObject("http://localhost:8070/product/get/" + orderParams.getProductId(), Product.class);
if (product == null){
throw new RuntimeException("未獲取到商品信息: " + JSONObject.toJSONString(orderParams));
}修改后的代碼片段如下所示。
Product product = restTemplate.getForObject("http://" + productUrl + "/product/get/" + orderParams.getProductId(), Product.class);
if (product == null){
throw new RuntimeException("未獲取到商品信息: " + JSONObject.toJSONString(orderParams));
}可以看到,訂單微服務(wù)獲取商品微服務(wù)信息時(shí),不再是硬編碼商品微服務(wù)的IP地址和端口號(hào)了。
(4)修改使用restTemplate扣減商品庫(kù)存的代碼片段,修改前的代碼片段如下所示。
Resultresult = restTemplate.getForObject("http://localhost:8070/product/update_count/" + orderParams.getProductId() + "/" + orderParams.getCount(), Result.class);
if (result.getCode() != HttpCode.SUCCESS){
throw new RuntimeException("庫(kù)存扣減失敗");
}
修改后的代碼片段如下所示。
Resultresult = restTemplate.getForObject("http://" + productUrl + "/product/update_count/" + orderParams.getProductId() + "/" + orderParams.getCount(), Result.class);
if (result.getCode() != HttpCode.SUCCESS){
throw new RuntimeException("庫(kù)存扣減失敗");
}
可以看到,訂單微服務(wù)調(diào)用商品微服務(wù)的扣減商品庫(kù)存接口時(shí),不再是硬編碼商品微服務(wù)的IP地址和端口號(hào)了。
注意:修改后的io.binghe.shop.order.service.impl.OrderServiceV2Impl 類的完整源碼,小伙伴們可自行查看項(xiàng)目代碼,冰河在這里不再贅述。
至此,整個(gè)項(xiàng)目就改造完成了。接下來(lái),我們進(jìn)行測(cè)試。
測(cè)試項(xiàng)目
開發(fā)完成后,我們對(duì)快速搭建并開發(fā)完成的三大微服務(wù)進(jìn)行簡(jiǎn)單的測(cè)試,在測(cè)試之前我們需要先在數(shù)據(jù)表中添加一些測(cè)試數(shù)據(jù)。
添加測(cè)試數(shù)據(jù)
(1)在用戶表中添加一條id為1001的記錄,如下所示。
INSERT INTO `shop`.`t_user`(`id`, `t_username`, `t_password`, `t_phone`, `t_address`) VALUES (1001, 'binghe', 'c26be8aaf53b15054896983b43eb6a65', '13212345678', '北京');
(2)在商品數(shù)據(jù)表中添加幾條商品記錄,如下所示。
INSERT INTO `shop`.`t_product`(`id`, `t_pro_name`, `t_pro_price`, `t_pro_stock`) VALUES (1001, '華為', 2399.00, 100);
INSERT INTO `shop`.`t_product`(`id`, `t_pro_name`, `t_pro_price`, `t_pro_stock`) VALUES (1002, '小米', 1999.00, 100);
INSERT INTO `shop`.`t_product`(`id`, `t_pro_name`, `t_pro_price`, `t_pro_stock`) VALUES (1003, 'iphone', 4999.00, 100);
測(cè)試庫(kù)存不足的情況
(1)分別啟動(dòng)用戶微服務(wù)、商品微服務(wù)和訂單微服務(wù)。
(2)查詢id為1001的商品信息,如下所示。
mysql> select * from t_product where id = 1001;
+------+------------+-------------+-------------+
| id | t_pro_name | t_pro_price | t_pro_stock |
+------+------------+-------------+-------------+
| 1001 | 華為 | 2399.00 | 100 |
+------+------------+-------------+-------------+
1 row in set (0.00 sec)
可以看到,id為1001的商品的庫(kù)存為100。
(3)查詢訂單表和訂單條目表中的數(shù)據(jù),如下所示。
- 查詢訂單表
mysql> select * from t_order;
Empty set (0.00 sec)
可以看到,訂單數(shù)據(jù)表的數(shù)據(jù)為空。
- 查詢訂單條目表
mysql> select * from t_order_item;
Empty set (0.00 sec)
可以看到,訂單條目數(shù)據(jù)表的數(shù)據(jù)為空。
(4)在瀏覽器中調(diào)用訂單微服務(wù)的下單接口,傳入的商品數(shù)量為1001,如下所示。
可以看到,返回的信息中,code為500,codeMsg輸出的信息為執(zhí)行失敗,data返回的結(jié)果為商品庫(kù)存不足,并且輸出了提交的參數(shù)信息。
(5)再次查詢id為1001的商品信息,如下所示。
mysql> select * from t_product where id = 1001;
+------+------------+-------------+-------------+
| id | t_pro_name | t_pro_price | t_pro_stock |
+------+------------+-------------+-------------+
| 1001 | 華為 | 2399.00 | 100 |
+------+------------+-------------+-------------+
1 row in set (0.00 sec)
可以看到,商品id為1001的商品庫(kù)存仍為100,并沒(méi)有減少。
(6)再次查詢訂單表和訂單條目表中的數(shù)據(jù),如下所示。
- 查詢訂單表
mysql> select * from t_order;
Empty set (0.00 sec)
可以看到,訂單數(shù)據(jù)表的數(shù)據(jù)為空。
- 查詢訂單條目表
mysql> select * from t_order_item;
Empty set (0.00 sec)
可以看到,訂單條目數(shù)據(jù)表的數(shù)據(jù)為空。
綜上,當(dāng)提交訂單時(shí)傳入的商品數(shù)量大于商品的庫(kù)存數(shù)量時(shí),系統(tǒng)會(huì)拋出異常,并不會(huì)執(zhí)行提交訂單和扣減庫(kù)存的操作。
測(cè)試正常下單的情況
(1)在測(cè)試庫(kù)存不足的情況的基礎(chǔ)上,我們將調(diào)用提交訂單的接口時(shí)傳入的商品數(shù)量修改為10,如下所示。
可以看到,當(dāng)商品庫(kù)存充足時(shí),調(diào)用訂單微服務(wù)的下單接口,返回的數(shù)據(jù)為success表示下單成功。
(2)再次查詢id為1001的商品信息,如下所示。
mysql> select * from t_product where id = 1001;
+------+------------+-------------+-------------+
| id | t_pro_name | t_pro_price | t_pro_stock |
+------+------------+-------------+-------------+
| 1001 | 華為 | 2399.00 | 90 |
+------+------------+-------------+-------------+
1 row in set (0.00 sec)
可以看到,id為1001的商品庫(kù)存由原來(lái)的100變更為90,減少了10個(gè)庫(kù)存。
(3)再次查詢訂單表和訂單條目表中的數(shù)據(jù),如下所示。
- 查詢訂單表
mysql> select * from t_order;
+------------------+-----------+-------------+-------------+-----------+---------------+
| id | t_user_id | t_user_name | t_phone | t_address | t_total_price |
+------------------+-----------+-------------+-------------+-----------+---------------+
| 3270016896208896 | 1001 | binghe | 13212345678 | 北京 | 23990.00 |
+------------------+-----------+-------------+-------------+-----------+---------------+
1 row in set (0.00 sec)
可以看到,訂單數(shù)據(jù)表中成功記錄了訂單的信息
- 查詢訂單條目表
mysql> select * from t_order_item;
+------------------+------------------+----------+------------+-------------+----------+
| id | t_order_id | t_pro_id | t_pro_name | t_pro_price | t_number |
+------------------+------------------+----------+------------+-------------+----------+
| 3270017277890560 | 3270016896208896 | 1001 | 華為 | 2399.00 | 10 |
+------------------+------------------+----------+------------+-------------+----------+
1 row in set (0.00 sec)
可以看到,訂單條目數(shù)據(jù)表中成功記錄了訂單條目的信息。
至此,項(xiàng)目的測(cè)試完畢。
分享題目:服務(wù)治理:實(shí)現(xiàn)服務(wù)的自動(dòng)注冊(cè)與發(fā)現(xiàn)
當(dāng)前URL:http://fisionsoft.com.cn/article/djhjgco.html


咨詢
建站咨詢
