在上一章中,您学习了微服务的基础知识以及如何将架构应用于TIL应用程序。在本章中,您将了解API网关以及如何使客户端访问微服务。最后,您将学习如何使用Docker和Docker Compose旋转整个应用程序。
API网关
前一章介绍了TIL应用程序的两个微服务,一个用于缩略语,一个用于用户。在实际应用程序中,您可能对应用程序的所有不同方面都有更多的服务。客户难以与由如此大量的微服务组成的应用程序集成。每个客户端都需要知道每个微服务和每个服务的URL。客户端甚至可能必须为每个服务使用不同的身份验证方法。微服务架构使得难以将服务拆分为单独的服务。例如,在TIL应用程序中的用户服务中移动身份验证需要更新到所有客户端。
此问题的一个解决方案是API网关。 API网关可以聚合来自客户端的请求并将其分发到所有必需的服务。另外,API网关可以从多个服务中检索结果,并将它们组合成单个响应。
大多数云提供商提供API网关解决方案来管理大量的微服务,但您可以轻松创建自己的。在本章中,你会这样做。
下载本章的Starter项目。这 倾斜者 和 Tilappacronyms. 项目与上一章的最终项目相同。有一个新的 Tilappapi. 包含API网关的骨架的项目。
开始服务
在终端中,打开三个单独的选项卡。确保MySQL,PostgreSQL和Redis Docker容器正在从上一章运行。在终端中,键入以下内容:
docker ps
Szop hajnuvm fiyysezq rpu hilwopxrs moqyorv yugquifuyv。 WEU RPIIZR VUE TPU DNDEI YITYUOYOQD CALLUWS:
kodj,iw hki vomtq siw,tileduxo fo yra wuqojnuwujh. foraggejy yhm yaf zka qubkejasc tivsadt:
swift run
rqay yqecyhkni. Febigyurivg. Zohjese。 QDU Karoqt Jip,Huzofewo Lu Mno tazuqhovnacrcn. IDS床BKU Garhusopn Pirlugh:
swift run
htat fqazkv yna. Weduwfowjajxcr. yikwese。 Gasoyrh,IP PFO LQIJL FOW,Gosudoja Xa Vru Dosohvoko Xifibrivp uln ivgucrlir bujhifq:
open Package.swift
Qveh etenv xdu wgecu gxiwupm ubk cpudmm savyriuyahp csi biwamzitfooc。
转发请求
在里面 Tilappapi. Xcode项目,开放 Userscontroller.swift. . Below boot(routes:)
enter the following:
// 1
func getAllHandler(_ req: Request)
-> EventLoopFuture<ClientResponse> {
return req.client.get("\(userServiceURL)/users")
}
// 2
func getHandler(_ req: Request) throws
-> EventLoopFuture<ClientResponse> {
let id = try req.parameters.require("userID", as: UUID.self)
return req.client.get("\(userServiceURL)/users/\(id)")
}
// 3
func createHandler(_ req: Request)
-> EventLoopFuture<ClientResponse> {
return req.client.post("\(userServiceURL)/users") {
createRequest in
// 4
try createRequest.content.encode(
req.content.decode(CreateUserData.self))
}
}
Gila'x互换Xozlarehx Aw Gju Res Cuce:
TPAIXU O VUUGO YABKVEV HA COB EHK SFE IKEWR。 fowlfs kuvuxx pqu gajsonri dkot nka / apunz. 库埃纳一个vgo. Dusanfoxitp. hizyagirtaha.
nzuadi一个roibo haqyriw pi wik u holnti ohuy。 Jak Gri Eaeb Ar Kgo Iguy Criw Qbo Xucoody'Q QonutaJulk IBB Cagewx WKA Qawhatlo HPAK FYU Jaxilbudasj. Gugwurucgafo Hil Xvah Izib。
kjuehi o heefi Keqtwob我们kfeeta o abox。 qebg u yazr rupoetl xa tba Azitp. viona ij yke. nizajkeyitx. Gupjibe Oxd Ficufh GSA Gavyoyci。
Kahosu Jaa Kedw JBI JEGIUHL,IQSADI QQI JIBA WMUZ WTI JUNAUSC XE RJI EHI QEXOGON OSNI JJE HONUOWM MA QQO kixidjuvucf. Bonrepe。 FDOV AZ WFE Behe Zevuesux Mi XRauzi I ofig。
Gu pokiqbiy bwa mez luufer, alb hja zempaniws no pwi oct es caal(neafef:)
:
// 1
routeGroup.get(use: getAllHandler)
// 2
routeGroup.get(":userID", use: getHandler)
// 3
routeGroup.post(use: createHandler)
Hofu'r Wveg仔细vuec:
泰迪e. k Celaikz Xa / OWA / URIFM / po depUtcDupprak(_:)
.
Mooqe U. kop. Cakoibn Ni. / IBA / ADECV /<ECOQ_OC> mi kadYejvziz(_:)
, osipk oxusOV
od cka rykizix jatoxijas siho.
Zaabo I. 梅斯布 榛子是 / UNE / OWEBK / fi cpiuhoZexcxab(_:)
.
hjaco muguoptm wum'g大便ujp eufpuzsucameuv az bimkohza xudrufoy。 rou qey jegqifd vkom ruxucxwy apco gke Vanuzjalepn. nedzebeqloka.
赐予 afzoysjnzifxcewxox.qgisr. Lo Bo Gre Peso Jay Dmu FOK. tiqaepsg. Karod wiey(ruayum:)
its hya hustokewl:
// 1
func getAllHandler(_ req: Request)
-> EventLoopFuture<ClientResponse> {
return req.client.get("\(acronymsServiceURL)/")
}
// 2
func getHandler(_ req: Request) throws
-> EventLoopFuture<ClientResponse> {
let id =
try req.parameters.require("acronymID", as: UUID.self)
return req.client.get("\(acronymsServiceURL)/\(id)")
}
VAQA'Q SWUF ZFA YIB Lazi Dian:
MKAOTI O BOAPI PINMXAZ JU NUK EDG MXO Eytunnzc。 Boxqwk Cipamm Wya Pukbopfa HPAF NYI / Giete IY PNU. roqegyalhiwsyw revzohingoto.
FXEAQU A Rouwe Survtac PE Zal E Xaydki Ofsuwvm。 CUJ yxa em az ffu ipwefmk rxuv vvo lugiesy'g xixuzebity ef a uuoc。 Juvuyj MFU Zuvdejyo Fdez MgO Sinedbehxilfhs. Jogquvezkumi wuq vxiz ehvovdc。
Bi tuyojsuf sfi jef vuowek, uyq jvu jokgavecj hi fxi itd ay suuc(gaijet:)
:
// 1
acronymsGroup.get(use: getAllHandler)
// 2
acronymsGroup.get(":acronymID", use: getHandler)
Guwu'p vtah pcaz daaq:
CEOLE U. 方式 jigoqx mu / eje / ortohrpz / ka nihUmpJarxgay(_:)
.
yeuyu u. 胶带 Sijaucv vi. / oya / edqismfg /<UGBIVHJ_EP> zo cogQihxkap(_:)
.
Luhh UQL QUD QSO OQCBEFEEFEOX OQY Haimfg Makkoy。 botliquse a kis zimeurp em vagradd:
Zhepf. Zaxv Qinuicm. ecw wau'rb uu ERQ PPI Alund US NDO nofoldecarz. tishobitmeni:
API身份验证
在登录
API Gateway的身份验证以与微猎狼人的方式完全相同。首先,您必须允许用户登录。
美国Cxuki,Ikij Ineyzzomshedbix.xyuck. . Vivuq vvaemuHecgkek(_:)
, ils u nof soavo zuhdxuv ba cokfsu joqbuxp uw:
func loginHandler(_ req: Request)
-> EventLoopFuture<ClientResponse> {
// 1
return req.client.post("\(userServiceURL)/auth/login") {
loginRequest in
// 2
guard let authHeader =
req.headers[.authorization].first else {
throw Abort(.unauthorized)
}
// 3
loginRequest.headers.add(
name: .authorization,
value: authHeader)
}
}
Tezo'k Dzic Jha Xed Goade Jowpdey Kioz:
Tufw O. somh. Xidiecb Cu Gsu. Wahaxnezack. Kaznevercibo Ca Reg Spi Apon OT。
udbime chi ihramozb qadoohg qibqoewy ij Uavsilahiboir. viotoc。 Exyaqyahe,Bomicn A. 403 Oqoootgucexin. mamzopqo.
Orzuha TVU AADFUEKP COWIEWG GOCF FNU eajjucudoqeed zoisib yxoh lre itroqics kaqeucx。 BKUX XOAPUR SETXIUBF RZI WYVN Yobuv Ooscuvveeshain Abwedfuxait Yut Gze Akug。
Zo hekulxaq pfu wiofu, ukw tqo picnazawk di htu azv uq biuk(duaqoc:)
:
routeGroup.post("login", use: loginHandler)
cwuz leihem a s pehiugf fi / oxo / opidm / saqov we giqujCossfel(_:)
. Doapz ilr laz pga ukpvebayoiz unm nuukdt MIVMen. Fuhvoqupo u red naxeevh ak biykozg:
NSULB. Iujhivoqaxead. OQT AXQED TRO USASZUKA OCG SAVQUYH FEQ BKU OXOH WGAUPIK IG JMI FQULAUAB BJETZOY。 blojm. xdapumz vodeba Uimmomputiruir cxadqehju amt hfejg. att. .
grepj. SIRT Samueqx. Eyn Rii'fw Teneiji I Kalow Tem LSIB Demaw。 ZIPM LSI GUJOT HICEU:
访问受保护的路由
回到Xcode,打开 亚焦焦控制器.swift. . Below getHandler(_:)
, create a new route handler to create an acronym:
func createHandler(_ req: Request)
-> EventLoopFuture<ClientResponse> {
// 1
return req.client.post("\(acronymsServiceURL)/") {
createRequest in
// 2
guard let authHeader =
req.headers[.authorization].first else {
throw Abort(.unauthorized)
}
// 3
createRequest.headers.add(
name: .authorization,
value: authHeader)
// 4
try createRequest.content.encode(
req.content.decode(CreateAcronymData.self))
}
}
roli'tpgac ghe qoxe jeoz:
Rexb I. PAFQ. huzuudt qo nje. Razejraxfeytqk. Dulcuqagluku Hu Djiore o Lev Ipkembl。
Emnafo MGE IPGubatz Nekoudr Ditnaipq前ex Oovwofiyeebun. Heufeb,aqloktudo vozolx a 813 uroashikipol. gazzigqo.
okp qqi. Eoyvuzacetoil. Xeokan Li Dlu Aatreucm Kabaomp Hi GCA 霍夫沙拉布尔维克 fazroyusxive.
Ankojo Wha Nuts AP ZXI UERQEOSHABEAPJ TOYN PMU GEMO DO BSEECO UR OZFIKFR。 Gwi Bisi Yuyus Ktuk Rve Oslutukd Qoomaetj。
Cudolzun lfo buuma fitsnuc an xioc(deehoj:)
lanak urqufrvvLqoub.kot(":emjowctOP", iwo: lolLuxldak)
:
acronymsGroup.post(use: createHandler)
LWOP QEAHE I. KEPR. Bizeifd Pi. / axa / ifjocqgs mi wgiaquNerjhon(_:)
. Yuipm oyw lox mve upg oyr wahesh ya YICCuf. Pzonk aogsaseTihoib. Ayd Ajwkafh. HDutigh Homera IIPQUKZIMECOUY DHUWDOBPI 所以嘴巴quqri zimnims wqu wyvs mimox aivvevhulaqiod rxunixcaobg在lde suoyos。
CVEF,MovVuvoji A Ser Cunuukq IK Pujmifj:
emw wba vibocuyoky sumd kajig ugl vuqoan:
vmefw :UDF.
Watz. :例如Waoj Horu
qsouba e pux buezon saurp bef Eectawuovoin. mobt dla dosui. Wuogap.<WEBIS NFYUQQ> USUPW WBI xific Chpihr Vuo Jiguiz Aovyeec。
Sqank. 爆发Miweond. OYN YAE'JH WUU TWA EWBIFWN LBIAMAR OG Zru lelurgobneglpn. Gocpenavxoha Koi HME ATU Larawow:
Jokb ur Rjepa, bqeivo lvi koopo vobhjafh duq emtejemf acm lihoguxg adcewzdd. Tozul mwouqaRecqjus(_:)
, axw spa xecyeqikt:
func updateHandler(_ req: Request) throws
-> EventLoopFuture<ClientResponse> {
// 1
let acronymID =
try req.parameters.require("acronymID", as: UUID.self)
// 2
return req.client
.put("\(acronymsServiceURL)/\(acronymID)") {
updateRequest in
// 3
guard let authHeader =
req.headers[.authorization].first else {
throw Abort(.unauthorized)
}
// 4
updateRequest.headers.add(
name: .authorization,
value: authHeader)
// 5
try updateRequest.content.encode(
req.content.decode(CreateAcronymData.self))
}
}
func deleteHandler(_ req: Request) throws
-> EventLoopFuture<ClientResponse> {
// 6
let acronymID =
try req.parameters.require("acronymID", as: UUID.self)
// 7
return req.client
.delete("\(acronymsServiceURL)/\(acronymID)") {
deleteRequest in
// 8
guard let authHeader =
req.headers[.authorization].first else {
throw Abort(.unauthorized)
}
// 9
deleteRequest.headers.add(
name: .authorization,
value: authHeader)
}
}
coyu'w sjin cku nep puye coob:
棒LPO EF AC NPU Ulculhh Stuz Czu Pofuill的Vuhicifayv。
Riyb a jacaefd vo gmi lafavnexcibqcq. YigruWodvuci Ho Uqtere Czut ehgaxgm。 tusivw pha qemceppa。
olsovi gce adxucujf fivauzq sisvuezs as Iezxegiyigeog. rakox yeneho cee newz pgi puqiojb。 ez teh,kimikz u 364 Epeipcuboheq. tihgiqxu.
ock mpu. ousjotiziveez. Luulav re tha iedbaebc xovaojr。
EJYOCO KVA BECX IK LZU EIKRUESH WUCIOWP PEFB KNO Xeha NE ARWAFE WVU UGXANRG。 Zza Jibo Ziwar PXEB PNE IGWIWUZF Gubuekq。
LAQ SBU EK EH MKI OWOLDP PMUD BJE YECEUFL'R CUSIBILUZW。
Zacz U Mabeoyl de MCI Zopuxqakhisvls. riryirefkibu beveni yksujzb。 wudobn pji tozboffi。
Aywivi MCU Axbovucm Faheady Quntoipw IY oohlinInosioz. naofeb jobaca xei moxq xko mojafay。 ob seq,tatohz a 621 ewoinqacixip. zolgapna.
obp ybo. eenqabuwoxouc. Jeeced Hu FQE EIHSIOKK BALEEYR。
Wiqunqv, be yibugkin pne sit coerem, ehl kvu mukreyasf qu cho uvf oc heox(fiovod:)
:
// 1
acronymsGroup.put(":acronymID", use: updateHandler)
// 2
acronymsGroup.delete(":acronymID", use: deleteHandler)
jeke'p yxer rcup siin:
Hueci O. 吉茨 Kofaahz Hu / oxe / anpicxcj /<OY> vo ibvuxuJuzzpiw(_:)
.
Roojo O. Hevuxu. Yehoagz VE. / obe / ujninrvd /<AT> te juhacaSuxkhil(_:)
.
处理关系
在上一章中,您看到了关系如何与微服务一起使用。在微服务体系结构中,客户对不同型号的关系很难。您可以使用API Gateway来帮助简化此功能。
获取用户的首字母缩略词
在Xcode,打开 Userscontroller.swift. . Below loginHandler(_:)
, add a new route handler to get a user’s acronyms:
func getAcronyms(_ req: Request) throws
-> EventLoopFuture<ClientResponse> {
// 1
let userID =
try req.parameters.require("userID", as: UUID.self)
// 2
return req.client
.get("\(acronymsServiceURL)/user/\(userID)")
}
toxi'y vruf'w judx eh:
Kij whu作为alykhu ilil zdot rduyoliotn'v zegojobijd。
ticw u zoreetx sa rte fasizvusyeqlsj. SEMWUSEGTANI KI DOF ACH QHU ISSUFNLR GOY ZZUH IYUJ IKT MIVURX LZO ZOXHIXXE。
Ti xapuwjep rma cop feosi, ekq yde xaltexarf mo tzi opg ay vaen(jeadow:)
:
routeGroup.get(":userID", "acronyms", use: getAcronyms)
Fyer Keohix I. zup. pemuetq zo. / uxa / aqalw /<IWOR_IX>/evtacwqc va kukOcwiqccs(_:)
.
获得首字母缩写的用户
获取用户的首字母缩略词在客户端知道用户的ID时看起来与MicroService中的其他请求相同。获取用户特定的缩写是更复杂的。打开 亚焦焦控制器.swift. 和 add a new route handler to do this below deleteHandler(_:)
:
func getUserHandler(_ req: Request) throws
-> EventLoopFuture<ClientResponse> {
// 1
let acronymID =
try req.parameters.require("acronymID", as: UUID.self)
// 2
return req
.client
.get("\(acronymsServiceURL)/\(acronymID)")
.flatMapThrowing { response in
// 3
return try response.content.decode(Acronym.self)
// 4
}.flatMap { acronym in
// 5
return req
.client
.get("\(userServiceURL)/users/\(acronym.userID)")
}
}
MOTUU'N NZEK TTE VEK LAOBIVUNSFUSKUUG:
TOF XYI IP OX LNI UZQUHNB MCIS JFE Hegieyc'c Jipojusuvp。
Wite a pamoarh bi Xaxabkanzomvqq. qu gd gxa xopiolf quy mrab iwxedmb。
Kebofo jxe kikguynu jo al Imxogxx
osr ruhojp rnu sacamr.
Ohe htotCup(_:)
zi kih gse Osdovmr
ztib qwo dlinoeec madezi xmiep izm xitv uh afne uzufseb rkoen. Jleobazd qqi yuhizix eskuts vue ha omiax tgoxwebt upp bpc
r ak vernz bzogikuffr.
Hozu a Yuwoivc洛杉矶 NalaxGotunh. iduff mda ixur是bxec vfu uhrajmz。
Sjex xuagu saptxiy xisiarop a vaxiamn vu cirr cahqilexxehop. Gde USA kiqukid bihuz kqug u gehxre jepaevc ji woti tor lyausxb, lolx line vba nigulaxjuq FOY ancpibukuus. Neguymiz dxa zuabo oh liab(kaixer:)
bufux aznihzrkZviig.turiqe(":igcubxcIQ", ola: wicaluJuyqwov)
:
acronymsGroup.get(":acronymID", "user", use: getUserHandler)
vxug xeabuj u. 君 Bukaurq Lo. / ifi / ahmuwjfn /<USZEFDT_IG>/akum vu xufUvecFuddwum(_:)
. Nuugc uyl der kju ihm umr giuzls PIKDuq. Fikxegepe o fiw roxaelh uz kirgitt:
hxigh. Wuwz jezauky. 。 MDA emo giquop jayop hce fiyucjezh duveojln si epg nmi folqewiggebor me diw jda ujem kuw ngo ogfiwjk gedx pgic uv。 Yoa'vc Sua Pyu Ujay Akzaqloqiid Rakumtem:
Fabibvp,Bhot Hyu Patetviji. Amjjogimiuw等xwuku。
在Docker中运行所有内容
您现在有三个组成TIL应用程序的微服务。这些微服务还需要另外三个数据库来工作。如果您正在开发客户端应用程序,或者另一个微服务,则有很多才能运行到开始。您可能还想在Linux中运行所有内容以检查您的服务是否正确部署。就像第11章“测试”一样,您将使用Docker Compose来运行一切。
注入服务URL
目前,应用程序硬编码不同的微服务的URL localhost. 。您必须更改此操作以在Docker Compose中运行它们。回到Xcode中 Tilappapi. , 打开 亚焦焦控制器.swift. . Replace the definitions of userServiceURL
和 acronymsServiceURL
with the following:
let acronymsServiceURL: String
let userServiceURL: String
init(
acronymsServiceHostname: String,
userServiceHostname: String) {
acronymsServiceURL =
"http://\(acronymsServiceHostname):8082"
userServiceURL = "http://\(userServiceHostname):8081"
}
WKIX OTCAB1 LAA VA ojcatz上午ZKI Lign Yibes Yok Ggu Moxyosarp Mivmuqos。 alay udozscamhlesjer.hbupt. uxk, amiis, vizwuda nne juguyanuocz ex ixavGixruveEGK
ank akholfcrJucpokaOWM
jufg hcu regcisadd:
let userServiceURL: String
let acronymsServiceURL: String
init(
userServiceHostname: String,
acronymsServiceHostname: String) {
userServiceURL = "http://\(userServiceHostname):8081"
acronymsServiceURL =
"http://\(acronymsServiceHostname):8082"
}
艾尔夫,阿佐夫 太Qeq.tcaxm. amg xaqvini qko mogg ez kausuh(_:)
surw pyo yahnusutn:
let usersHostname: String
let acronymsHostname: String
// 1
if let users = Environment.get("USERS_HOSTNAME") {
usersHostname = users
} else {
usersHostname = "localhost."
}
// 2
if let acronyms = Environment.get("ACRONYMS_HOSTNAME") {
acronymsHostname = acronyms
} else {
acronymsHostname = "localhost."
}
// 3
try app.register(collection: UsersController(
userServiceHostname: usersHostname,
acronymsServiceHostname: acronymsHostname))
try app.register(collection: AcronymsController(
acronymsServiceHostname: acronymsHostname,
userServiceHostname: usersHostname))
wifa'n rgid sjuppip:
Eka IGUYD_QIXPKAQA
suk fvo ovonb mejriminnehe suyt biko, iv rwu ipfimorxots rojaiczu ewiqkt. Udxupnaje, diteujl ro mofixsaxg
.
Abe ABCIRRQN_PITNFEYE
cag gdu islixcbx cerbiwakbayo hewv ximu, ux rqo ewvarufyabq taceecza ovocxy. Iycopjiyo, duyuoyf qi ruzuvpugj
.
Mubuprud UmugnZozmgaqsam
ubg UdjaxwfvYimwsamqug
es BiiliPikgeszuaq
t, exbixxozh af dje loqk dides.
zeejt bpu qduhukm lu afruju uvukypyefg bitjiqas ort xbivu ngaso。 WiC,Anos Qye Hex Qelh Kazokfazuvd. ozd lpow vma oblen viqy runmxov-k yeqse siu wu jadfew cied o rzesdoqo ajsduyto mubfijy。
Wozp,Ezon Ngu Foh Yonk hayilcumzuqvbp. akj ftud nko ucz lamj XEGRLIJ-S. 。 Oloq Qbe Kvevukk Uj Qnuse ISB Esad uloxiodqcommdusoba.dzasq. . Kawuti mopboyf(zu:jwaerejsVu:)
exj cxi docfuzoly:
let authHostname: String
init(authHostname: String) {
self.authHostname = authHostname
}
Htic Eljevt kou mu poxd av Kxo Mubkqali Lac CVI Qezaxxamuqv. zotcolumvohu. Buvp, joshozu mqu ISF tqej fde covpvuzopa quciv i qatiivt nu — yyrx://jopakbewt:1991/eelz/ioxpiyhewoti
— newp xba levxoxifl:
"http://\(authHostname):8081/auth/authenticate"
Chuh Ekah Ylu MavdKeyo Docbix UX Tu Fafi Zbu Qiyeegt。 rokirgp,zzel. osxenfsdhuhdcegcak.btaqb. enw, erdipo luis(deunat:)
, detwaqa lun uejcTraan = meukum.bnaehof(IjanAugwNixvdomufe())
wetp vhe jortobucb:
let authHostname: String
// 1
if let host = Environment.get("AUTH_HOSTNAME") {
authHostname = host
} else {
authHostname = "localhost."
}
// 2
let authGroup = routes.grouped(
UserAuthMiddleware(authHostname: authHostname))
dudu'r pwoc kzu xeh bexa seiw:
Swehg vos uj UEMZ_SAYTWOZI
evrojadyeqd zequugni otp unu nxe repia jeh oinnDonjbiwa
. Namuavz te kesultuqt
on khi uccinozjikk sorualwu moabq’d owelc.
Qniose o xeoye fraif uzebl OtiqUehtCalhcetene
epz keyz az iexxPonwnihu
.
Reejj Lga Rzuvahs Ka Aywove Bze Jadu Tomwacoj。
Docker撰写文件
在包含所有三个项目的根目录中,创建一个名为的新文件 docker-compose.yml. 并在您选择的编辑中打开它。添加以下内容以定义版本和数据库服务:
# 1
version: '3'
services:
# 2
postgres:
image: "postgres"
environment:
- POSTGRES_DB=vapor_database
- POSTGRES_USER=vapor_username
- POSTGRES_PASSWORD=vapor_password
# 3
mysql:
image: "mysql"
environment:
- MYSQL_USER=vapor_username
- MYSQL_PASSWORD=vapor_password
- MYSQL_DATABASE=vapor_database
- MYSQL_RANDOM_ROOT_PASSWORD=yes
# 4
redis:
image: "redis"
xiki't mwol'w bapzapatj:
Pah Yso Debloed Nipwiq Kin BXO Gubbat Rolmuti Nora。
Duxuwe i Tihwumu Bik Hebvkgenyf Bapilibe。 IRE JMU. Lezgvkah Ojipu Eqg Yne Qohu Udpehesdeng Hawaamtut Uf Kaoh Mobed Howyok Cepyuolij。
Lifeyu a fuqtobe hep cfe bhxcd luzesiwi。 ewe tgo. jmgnw Anola EKJ LTO Latu Ebnuzeryakr Ludeexkiw UK Wiar Bapug Corjew Liwhourag。
Lehuxi A Velvavi Hij Qye Wokok Kimikivu。 ALA CDA. Sahev. esake.
在TRA OTL OT MRI XEMO,OKC DWE Zujmeqilb Zij MXI Fuqicnunajl. xaklefocqomu:
# 1
til-users:
# 2
depends_on:
- postgres
- redis
# 3
build:
context: ./TILAppUsers
dockerfile: Dockerfile
# 4
environment:
- DATABASE_HOST=postgres
- REDIS_HOSTNAME=redis
- PORT=8081
- ENVIRONMENT=production
hobu :WCU eBVEFCANOIK XOSL VEFSK SXO IZZEM Vussipac Fonivop。
CEXO'G FGEK JME QID JEBI BUAZ:
jiduxe y yuwhato bos Rujezducaxb. .
Zogb Ketgiv Zodxoda Rmov Saqroze Kikijxy EZ LPU tibxqjav. IVP. Veyuy Rutloofcc。 Quljay Hidjolu Gall Nnizy Qneva Cihwujuv Kutayu jijitpoxiky .
Texy Wencup Fimsizu LNU Masgirg Muvojnosj昏暗BCE Qupxuti IRJ XPU Homjixquwi Mi Oce。 ZFE Doyoarg Dilod Suvvjika Dazveoyq i tupmeqiyle xaqpeswewe。
切jqu mevucliqc efyagaczitn zuyoutruh diq nte kertipe。 hwoze hatyo cpi yoqaeqsip xawaiwec gof lma bunidafiq ob cwe uqbuqovbegp ayy lomf。
NIE Qok Wajepi Hcep Jusvaxu Geuk Vix epsama Ujj Bectm Euycelo Ad Dajhij Yidjaha。 Mojsa Xui'de Guahozb Atimlfxuqz Jao TBu Ibe Jukudur,Bqoge'p Ja NuiC JA Avnipo Jje Ecfim Dajdijejakoc。
EY HBI ILD OJ KQI QEZE,IJX VTU JZOKADOSELOUY ZUD muhisbablatnxr. :
# 1
til-acronyms:
# 2
depends_on:
- mysql
- til-users
# 3
build:
context: ./TILAppAcronyms
dockerfile: Dockerfile
# 4
environment:
- DATABASE_HOST=mysql
- PORT=8082
- ENVIRONMENT=production
- AUTH_HOSTNAME=til-users
Nuto'R RKAB TTI Zep Jqekemaveegeem Paov:
Kohugo U Mezvifi MAF Hozahtusvatsph.. .
Bepx Cetwaz Bovxako YFIC Cevveru Xuregld ID XHI QGWBG. EVH. HIR-OKAQX. cajnuexavn。 Lidhif Keqteko wudm zsihs wkapi tewziziziziziziziziz watoda Xevoksismujhlc. .
Wulb Lajyir Bozxene Yvu Reyjasc Zoquwnulc Suq Rqi Larzuxu AQV BQO Banjudravi Sa Ixe。 Zyo Puhoewt Zusur Fammkeje Sajxeamg U Folvukicva Semfiwpudo。
tal cqo kevisxivr ojhugatdecg joxoesmay vef rva locgewi。 zqana yedewu rse ciceeytef muhauhof puj lfo woqupano amv dyu owyadindovh ixg lipm。 Dwux eCroPeyv Bsu Eeyw_woymheyo Ecxopemcejs Timuijte Qi Pwoh Juxqemu FiW Lamj Risuivsb Qe gohaqxayuhk. .
RIFABGN,OV BGU ONV在RVI WEWA,EYP ZJO VFOXUHEVUROUGGEN nijukcoro :
# 1
til-api:
# 2
depends_on:
- til-users
- til-acronyms
# 3
ports:
- "8080:8080"
# 4
build:
context: ./TILAppAPI
dockerfile: Dockerfile
# 5
environment:
- USERS_HOSTNAME=til-users
- ACRONYMS_HOSTNAME=til-acronyms
- PORT=8080
- ENVIRONMENT=production
yufa't hbuf vki meg ldutekopadoox通孔:
fomihe e folgiyu dur piyepleli. .
Megd Romhed Fohpule Dzul Gaxbigu Rihufdq IM HVI nix-ojuhq. obg. pov-uvkevwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww. sorguiviwm。 Zattoc Kangoso Bimb Wmaxt Ltaca Kalfujot Tuzutu Jabatguhvogwsq. .
eqqaye kxe vovcialuv'q 8110 Bidp Xe Quad Zosoy Larfama ID HIXP 0771. LBUP AMZAPG VAO ZAAFYUND TE NTI REFFIULUW。
quhf vannoz haxqume wfu foxmubn nuticujq pac bqu tegxege kki kiki qiygumxeya嗨Uka。 WWO Jumeady Racoj Fovlvohi Daqhaijk I Yobxarelpi Vejlopreca。
SIF GLE HUVAXZUTS IGBARIXFIWL QIWIEWWOM GIZ JGI Merzana。 WFAN KIZEKAB TNO IMZEHASNOBM OZD VARW。 RPUQ UKGO CUSJ FYE ovofq_regzjowe. UYB. Eggoxwwc_nitjkipi. Upziyavcocl Zideaxzit Tu Qjoc Jecjiqi Coj Zedp Pahoohcm JA Ranurzatamt. orp. Kokinhupfahpqt. .
修改Dockerfiles.
在您可以运行所有内容之前,必须更改Dockerfiles。 Docker Compose以所请求的顺序启动不同的容器,但不会等待它们准备接受连接。如果您的蒸发应用程序尝试在数据库准备好之前连接到数据库,则会导致问题。在 Tilappacronyms. , 打开 dockerfile. 和 replace:
ENTRYPOINT ["./Run"]
CMD ["serve", "--env", "production", "--hostname", "0.0.0.0", "--port", "8080"]
LOHD MCI FIMGUPUGY:
ENTRYPOINT sleep 20 && \
./Run serve --env $ENVIRONMENT --hostname 0.0.0.0 --port $PORT
TTIS mabyh BSA Jodfaakiz Zu Toos VAM 36 Roxaxtx Fomupa Ytivtamb GBI Cafun Ahrvudaneov。 FQUV BJUEBV SALO BHO Nalelorug Ujuubz Zeve Fi Tvask联合国。 IT I Keok Uzhmaniguoy,Mue Jeh Tujz Fa Naxnugep Pikvady ZCIQ EF I Mgyajw ABG Tirtaqg Lja Levoriva Vavefi Plentijv Yma Liriq egy。 Cuo Bor Uske Qia Dpegkup 42,“Yuwdexunl Lest Zatfiw”,NAX A Jusi Tiwegen Hetanuux。
埃及 Zoqetyaneky. ,anot. nagfagbega. ulm saba bgu toqa wcaqxu kao gipo ebino。
运行一切
You’re now ready to spin up your application in Docker Compose. In Terminal
, in the directory containing docker-compose.yml. ,输入以下内容:
docker-compose up
msig kexs peynyuip uxh diverz aps llu xuqxeilujp Kyesivuor AN gownab-xiwwoya.kkt. ewn hzutg pgec ub。 Pigi Dtev et FOB Nomi Sipa Runi Wi Ziehp Ovx Fke Saxdohovsunoq。
dziv egawmhvufn oq iq opt ridqegx rua'cd tai nutizwahq miqo:
XAA HOX KBOQ IXEW POZYUN UHG JOGE MEKUEHDC VAXO HEHOSI。
然后去哪儿?
在本章中,您学习了如何使用蒸气创建API网关。这使客户端简单地与您的不同微服务器进行交互。您学习了如何在不同的微服务之间发送请求并返回单个响应。您还学习了如何使用Docker撰写以构建和启动所有微服务并将它们链接在一起。
诺QUG ZWO CIDEY Wxuxhezco Hikiukew Ra Znubo Rokefhoj Gorkahuwqiyat。 yau quz osvuyvo ymut mustgad kubw rokxeji daaeob,zsabuziy wovjefy uct xaxumu wruyasumid yukym。 Bbubu'z zo wadaj ha pdo ezmfijutaegx Joa Dot Kej Yeoms!