
Å ajÄ rakstÄ detalizÄti skaidrots, kÄ risinÄt problÄmas, kas saistÄ«tas ar datu bÄzu saderÄ«bu, veicot izvietoÅ”anu. MÄs pastÄstÄ«sim, kas var notikt ar jÅ«su ražoÅ”anas lietojumprogrammÄm, ja mÄÄ£inÄsiet veikt izvietoÅ”anu bez iepriekÅ”Äjas sagatavoÅ”anas. PÄc tam mÄs iziesim cauri lietojumprogrammas dzÄ«ves cikla posmiem, kas ir nepiecieÅ”ami, lai nodroÅ”inÄtu nulles dÄ«kstÄvi (piezÄ«me: turpmÄk ā nulles dÄ«kstÄve). MÅ«su darbÄ«bu rezultÄts bÅ«s atpakaļsaderÄ«gu datu bÄzes izmaiÅu piemÄroÅ”ana.
Ja vÄlaties iepazÄ«ties ar rakstÄ iekļautajiem kodu piemÄriem, jÅ«s tos atradÄ«siet .
Ievads
Nulles dÄ«kstÄves izvietoÅ”ana
Kas ir Å”is noslÄpumainais nulles dÄ«kstÄves izvietojums? ŠŠ¾Š¶Š½Š¾ ŃŠŗŠ°Š·Š°ŃŃ, ŃŃŠ¾ когГа Š²Š°Ńе ŠæŃиложение ŃŠ°Š·Š²ŠµŃнŃŃŠ¾ ŃŠ°Šŗ, ŃŃŠ¾ Š²Ń Š¼Š¾Š¶ŠµŃŠµ ŃŃŠæŠµŃŠ½Š¾ ввоГиŃŃ Š½Š¾Š²ŃŃ Š²ŠµŃŃŠøŃ ŠæŃŠøŠ»Š¾Š¶ŠµŠ½ŠøŃ на ŠæŃŠ¾Š“Š°ŠŗŃŠ½, в ŃŠ¾ Š²ŃŠµŠ¼Ń как ŠæŠ¾Š»ŃŠ·Š¾Š²Š°ŃŠµŠ»Ń Š½Šµ Š·Š°Š¼ŠµŃŠ°ŠµŃ его неГоŃŃŃŠæŠ½Š¾ŃŃŠø. Š” ŃŠ¾ŃŠŗŠø Š·ŃŠµŠ½ŠøŃ ŠæŠ¾Š»ŃŠ·Š¾Š²Š°ŃŠµŠ»Ń Šø компании, ŃŃŠ¾ наилŃŃŃŠøŠ¹ ŠøŠ· возможнŃŃ ŃŃŠµŠ½Š°Ńиев ГеплоŃ, ŠæŠ¾ŃŠŗŠ¾Š»ŃŠŗŃ ŃŠ°ŠŗŠøŠ¼ Š¾Š±ŃŠ°Š·Š¾Š¼ можно ввоГиŃŃ Š½Š¾Š²ŃŠµ ŃŃŠ½ŠŗŃŠøŠø Šø ŃŃŃŃŠ°Š½ŃŃŃ Š¾ŃŠøŠ±ŠŗŠø без ŠæŠµŃŠµŠ±Š¾ŠµŠ² в ŃŠ°Š±Š¾Ńе.
KÄ to sasniegt? Ir vairÄki veidi; Å”is ir viens no tiem:
- izvietojiet savu pakalpojuma versiju Nr. 1
- veiciet datu bÄzes migrÄciju
- izvietojiet pakalpojuma versiju Nr. 2 paralÄli versijai Nr. 1
- uzreiz, kad redzat, ka versija Nr. 2 darbojas pareizi, noÅemiet versiju Nr. 1
- gatavs!
Viegls, vai ne? DiemžÄl tas nav tik vienkÄrÅ”i, un mÄs vÄlÄk par to detalizÄti diskutÄsim. Tagad paskatÄ«simies uz vÄl vienu diezgan izplatÄ«tu izvietoÅ”anas procesu ā zibens zaļo izvietoÅ”anu.
Vai esat dzirdÄjuÅ”i par ? Š” Cloud Foundry ŃŃŠ¾ ŃŃŠµŠ·Š²ŃŃŠ°Š¹Š½Š¾ легко ŃŠ“елаŃŃ. ŠŃоŃŃŠ¾ Š³Š»ŃŠ½ŃŃŠµ на , kur mÄs to aprakstÄm sÄ«kÄk. ÄŖsi sakot, atgÄdinÄsim, kÄ veikt zibens zaļo izvietoÅ”anu:
- nodroÅ”iniet, lai divas jÅ«su ražoÅ”anas koda kopijas (āzilaā un āzaļaā) darbotos;
- virziet visu trafiku uz zilo vidi, t.i., lai ražoÅ”anas URL norÄdÄ«tu uz to;
- izvietojiet un pÄrbaudiet visus lietojumprogrammas izmaiÅu zaļajÄ vidÄ;
- pÄrslÄdziet URL adreses no zilÄs uz zaļo vidi
Zibens zaÄ¼Ä izvietoÅ”ana ir pieeja, kas ļauj jums viegli ieviest jaunas funkcijas, neriskÄjot, ka ražoÅ”anas vide sabojÄsies. Tas saistÄ«ts ar to, ka pat ja kaut kas notiek, jÅ«s varat viegli atgriezties iepriekÅ”ÄjÄ vidÄ, vienkÄrÅ”i āpÄrslÄdzot slÄdziā.
Izlasot iepriekÅ” minÄto, jÅ«s varÄtu uzdot jautÄjumu: kÄda saistÄ«ba ir nulles dÄ«kstÄvei ar zibens zaļo izvietoÅ”anu?
Nu, tÄm ir diezgan daudz kopÄ«ga, jo divu vienas un tÄs paÅ”as vides kopiju uzturÄÅ”ana prasa dubultus centienus to apkalpoÅ”anai. TÄdÄļ daži komandas, kÄ apgalvo , ievÄro Ŕī pieejas variÄciju:
Otra iespÄja ir izmantot to paÅ”u datu bÄzi, izveidojot zilzaļÄs slÄdžus tÄ«mekļa un domÄna slÄÅiem. Å ÄdÄ pieejÄ datu bÄzes bieži var kļūt par problÄmu, Ä«paÅ”i, ja jums ir jÄpÄrveido tÄs shÄma, lai atbalstÄ«tu jauno programmatÅ«ras versiju.
Un Å”eit mÄs nonÄkam pie galvenÄs problÄmas Å”ajÄ rakstÄ. Datu bÄze. ApskatÄ«sim Å”o frÄzi vÄlreiz.
veiciet datu bÄzes migrÄciju.
Tagad jums jÄuzdod sev jautÄjums - kas notiks, ja datu bÄzes izmaiÅas bÅ«s neapmierinoÅ”as? Vai mana pirmÄ lietotnes versija nesabruks? PatiesÄ«bÄ, tieÅ”i tas notiks...
TÄdÄjÄdi, neraugoties uz milzÄ«gajÄm priekÅ”rocÄ«bÄm, kas saistÄ«tas ar zero downtime / blue green deployment, uzÅÄmumi mÄdz ievÄrot Å”Ädu droÅ”Äku lietotÅu izvietoÅ”anas procesu:
- sagatavot pakotni ar jauno lietotnes versiju
- izslÄgt palaisto lietotni
- izpildÄ«t skriptus datu bÄzes migrÄcijai
- izvietot un palaist jauno lietotnes versiju
Å ajÄ rakstÄ mÄs detalizÄti aprakstÄ«sim, kÄ jÅ«s varat strÄdÄt ar datu bÄzi un kodu, lai gÅ«tu labumu no zero downtime deployment.
ProblÄmas ar datu bÄzi
Ja jums ir stateless lietotne, kas neglabÄ nekÄdus datus datu bÄzÄ, jÅ«s varat iegÅ«t zero downtime deployment uzreiz. DiemžÄl lielÄkÄ daļa programmatÅ«ras ir jÄuzglabÄ kaut kur. TÄpÄc jums ir divreiz jÄpÄrdomÄ, pirms veicat jebkÄdas izmaiÅas shÄmÄ. Pirms mÄs iegrimsim detaļÄs par to, kÄ mainÄ«t shÄmu tÄ, lai bÅ«tu iespÄjams izvietot bez dÄ«kstÄves, vispirms koncentrÄsimies uz versiju vadÄ«bas shÄmu.
Versiju vadÄ«bas shÄma
Å ajÄ rakstÄ mÄs izmantosim kÄ versiju vadÄ«bas rÄ«ku (piezÄ«me: runa ir par datu bÄzes migrÄcijÄm). Protams, mÄs arÄ« uzrakstÄ«sim Spring Boot lietotni, kurai ir iebÅ«vÄta Flyway atbalsts un kas veiks shÄmas migrÄciju lietotnes konteksta iestatīŔanas laikÄ. Izmantojot Flyway, jÅ«s varat saglabÄt migrÄcijas skriptus savus projektu mapÄs (pÄc noklusÄjuma classpath:db/migration). Å eit jÅ«s varat redzÄt Å”Ädu migrÄcijas failu piemÄru
āāā db
āāā migration
āāā V1__init.sql
āāā V2__Add_surname.sql
āāā V3__Final_migration.sql
āāā V4__Remove_lastname.sqlÅ ajÄ piemÄrÄ mÄs redzam 4 migrÄcijas scenÄrijus, kas, ja tie iepriekÅ” nebija veikti, tiks izpildÄ«ti viens pÄc otra, palaižot lietojumprogrammu. ApskatÄ«sim vienu no failiem (V1__init.sql) kÄ piemÄru.
IZVEIDOT TABULU PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
fist_name varchar(255) not null,
last_name varchar(255) not null
);
ielikt iekÅ”Ä PERSON (first_name, last_name) vÄrtÄ«bas ('Dave', 'Syer');Viss skaisti runÄ pats par sevi: jÅ«s varat izmantot SQL, lai noteiktu, kÄ jÅ«su datubÄze bÅ«tu jÄmaina. Lai iegÅ«tu papildu informÄciju par Spring Boot un Flyway, iepazÄ«stieties ar .
Izmantojot versiju pÄrvaldÄ«bas rÄ«ku kopÄ ar Spring Boot, jÅ«s saÅemat 2 lielas priekÅ”rocÄ«bas:
- jÅ«s atdalÄt datubÄzes izmaiÅas no koda izmaiÅÄm
- datubÄzes migrÄcija notiek vienlaikus ar jÅ«su lietojumprogrammas laiÅ”anu tirgÅ«, tas ir, jÅ«su izvietoÅ”anas process tiek atvieglots
ProblÄmu risinÄÅ”ana saistÄ«bÄ ar datubÄzi
NÄkoÅ”ajÄ sadaÄ¼Ä mÄs koncentrÄsimies uz divu pieeju pÄrskatu saistÄ«bÄ ar datubÄzes izmaiÅÄm.
- atpakaļsaderība
- atpakaļsaderības
Pirmais tiks apskatÄ«ts kÄ brÄ«dinÄjums, ka nevajadzÄtu veikt bezdarbÄ«bas izvietojumus bez iepriekÅ”Äjas sagatavoÅ”anÄs⦠Otrais piedÄvÄ risinÄjumu, kÄ var veikt izvietoÅ”anu bez pÄrtraukumiem un vienlaikus saglabÄt atpakaļsaderÄ«bu.
MÅ«su projekts, ar kuru mÄs strÄdÄsim, bÅ«s vienkÄrÅ”a Spring Boot Flyway lietojumprogramma, kurÄ ir Person ar first_name un last_name datubÄzÄ (piezÄ«me: Person ir tabula, bet first_name un last_name ā tas ir lauks tajÄ). MÄs vÄlamies pÄrdÄvÄt last_name par uzvÄrdu.
PieÅÄmumi
Pirms mÄs iedziļinÄmies detaļÄs, nepiecieÅ”ams izvirzÄ«t pÄris pieÅÄmumus attiecÄ«bÄ uz mÅ«su lietojumprogrammÄm. Galvenais rezultÄts, ko mÄs vÄlamies sasniegt, bÅ«s diezgan vienkÄrÅ”s process.
PiezÄ«me. Business PRO-TIP. Procesu vienkÄrÅ”oÅ”ana var ietaupÄ«t jums daudz naudas atbalstam (jo vairÄk cilvÄku strÄdÄ jÅ«su uzÅÄmumÄ, jo vairÄk naudas jÅ«s varat ietaupÄ«t)!
Nav nepiecieÅ”ams veikt datubÄzes atgrieÅ”anu
Tas atvieglo izvietoÅ”anas procesu (dažas datubÄzes atgrieÅ”anas ir praktiski neiespÄjamas, piemÄram, dzÄÅ”anas atgrieÅ”ana). MÄs dodam priekÅ”roku atgriezt tikai lietojumprogrammas. TÄdÄjÄdi, pat ja jums ir dažÄdas datubÄzes (piemÄram, SQL un NoSQL), jÅ«su izvietoÅ”anas lÄ«nija izskatÄ«sies vienÄdi.
Ir jÄnodroÅ”ina, lai vienmÄr bÅ«tu iespÄja atgriezt lietojumprogrammu par vienu versiju atpakaļ (ne vairÄk)
AtgrieÅ”ana jÄveic tikai nepiecieÅ”amÄ«bas gadÄ«jumÄ. Ja paÅ”reizÄjÄ versijÄ ir kļūda, kuru nav viegli novÄrst, mums jÄbÅ«t spÄjÄ«giem atgriezties pie pÄdÄjÄs darba versijas. MÄs pieÅemam, ka Ŕī pÄdÄjÄ darba versija ir iepriekÅ”ÄjÄ. AtbalstÄ«t saderÄ«bu ar kodu un datu bÄzi vairÄk nekÄ vienai izlaidumam bÅ«tu ÄrkÄrtÄ«gi grÅ«ti un dÄrgi.
PiezÄ«me. Lai uzlabotu lasÄmÄ«bu, Å”ajÄ rakstÄ mÄs mainÄ«sim lietojumprogrammas galveno versiju.
1. solis: sÄkotnÄjais stÄvoklis
Lietojumprogrammas versija: 1.0.0
Datu bÄzes versija: v1
KomentÄrs
Tas bÅ«s lietojumprogrammas sÄkotnÄjais stÄvoklis.
Datu bÄzes izmaiÅas
Datu bÄze satur last_name.
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');Koda izmaiÅas
Lietojumprogramma saglabÄ datus Person last_name:
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastname) {
this.lastName = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName
+ "]";
}
}Atpakaļ nesavienojama kolonnas pÄrdÄvÄÅ”ana
ApskatÄ«sim piemÄru, kÄ mainÄ«t kolonnas nosaukumu:
UzmanÄ«bu. NÄkamais piemÄrs apzinÄti izraisa kļūmi. MÄs to rÄdÄm, lai demonstrÄtu datu bÄzes saderÄ«bas problÄmu.
Lietojumprogrammas versija: 2.0.0.BAD
Datu bÄzes versija: v2bad
KomentÄrs
PaÅ”reizÄjÄs izmaiÅas NEļauj mums palaist divus instancus (veco un jauno) vienlaikus. TÄdÄjÄdi bezpÄrtraukta izvietoÅ”ana bÅ«s grÅ«ti sasniedzama (Åemot vÄrÄ pieÅÄmumus, tas patiesÄ«bÄ ir neiespÄjami).
A/B testÄÅ”ana
PaÅ”reizÄjÄ situÄcija ir tÄda, ka mums ir lietojumprogramma versijÄ 1.0.0, izvietota ražoÅ”anas vidÄ, un datu bÄze v1. Mums jÄizvieto otrais lietojumprogrammas instants, versijÄ 2.0.0.BAD, un jÄatjaunina datu bÄze lÄ«dz v2bad.
Soli pa solim:
- ir izvietots jaunais lietojumprogrammas instants versijÄ
2.0.0.BAD, kas atjaunina datu bÄzi lÄ«dzv2bad - datu bÄzÄ
v2badkolonnalast_namevairs neeksistÄ ā to ir mainÄ«jusiuzvÄrdu - datu bÄzes un lietojumprogrammas atjauninÄjums ir veiksmÄ«gi pabeigts, un daži instanci darbojas
1.0.0, citi ā2.0.0.BAD. Visi ir saistÄ«ti ar datu bÄziv2bad - visi instanci versijÄ
1.0.0sÄks izsist kļūdas, jo tie centÄ«sies ievietot datus kolonnÄlast_name, kuru vairs nav - visi instanci versijÄ
2.0.0.BADdarbojas bez problÄmÄm
KÄ redzat, ja mÄs veicam atpakaļ nesavienojamas datu bÄzes un lietojumprogrammas izmaiÅas, A/B testÄÅ”ana nav iespÄjama.
Lietojumprogrammas atgrieŔana
PieÅemsim, ka pÄc mÄÄ£inÄjuma veikt A/B izvietoÅ”anu (piezÄ«me: iespÄjams, autors Å”eit domÄja A/B testÄÅ”anu) mÄs nolemjam, ka mums jÄpÄrgatavojas lietojumprogrammai uz versiju 1.0.0. PieÅemsim, ka mÄs nevÄlamies veikt datu bÄzes atgrieÅ”anu.
Soli pa solim:
- mÄs apturÄm programmas instanci versijÄ
2.0.0.BAD - datubÄze joprojÄm
v2bad - jo versija
1.0.0neizprot, kas iruzvÄrdu, mÄs redzÄsim kļūdas - ellÄ izlauzÄs brÄ«vÄ«bÄ, mÄs vairs nevaram atgriezties
KÄ redzat, ja veicam atpakaļ nesaderÄ«gas izmaiÅas BŠ un programmÄ, mÄs nevaram atgriezties pie iepriekÅ”ÄjÄs versijas.
Izpildes skriptu žurnÄli
Atpakaļ nesaderÄ«gs scenÄrijs:
01) Izpildiet 1.0.0
02) Gaidiet, lÄ«dz programma (1.0.0) ielÄdÄjas
03) Radiet personu, zvanot POST localhost:9991/person versijai 1.0.0
04) Izpildiet 2.0.0.BAD
05) Gaidiet, lÄ«dz programma (2.0.0.BAD) ielÄdÄjas
06) Radiet personu, zvanot POST localhost:9991/person versijai 1.0.0 <-- tam jÄneizdodas
07) Radiet personu, zvanot POST localhost:9992/person versijai 2.0.0.BAD <-- tam jÄizdodas
SÄkot programmu versijÄ 1.0.0
RadīŔana personai versijÄ 1.0.0
SÅ«tot pieprasÄ«jumu uz 127.0.0.1:9991/person. Tas ir atbildes rezultÄts:
{"firstName":"b73f639f-e176-4463-bf26-1135aace2f57","lastName":"b73f639f-e176-4463-bf26-1135aace2f57"}
SÄkot programmu versijÄ 2.0.0.BAD
RadīŔana personai versijÄ 1.0.0
SÅ«tot pieprasÄ«jumu uz 127.0.0.1:9991/person. Tas ir atbildes rezultÄts:
curl: (22) PieprasÄ«tÄ URL atgrieza kļūdu: 500 IekÅ”ÄjÄ servera kļūda
RadīŔana personai versijÄ 2.0.0.BAD
SÅ«tot pieprasÄ«jumu uz 127.0.0.1:9995/person. Tas ir atbildes rezultÄts:
{"firstName":"e156be2e-06b6-4730-9c43-6e14cfcda125","surname":"e156be2e-06b6-4730-9c43-6e14cfcda125"}Datu bÄzes izmaiÅas
MigrÄcijas skripts, kas pÄrdÄvÄ last_name par uzvÄrdu
OriÄ£inÄlais Flyway skripts:
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');Skripts, kas pÄrdÄvÄ last_name.
-- Å Ä« izmaiÅa ir atpakaļ nesaderÄ«ga - jums nav iespÄjams veikt A/B testÄÅ”anu
ALTER TABLE PERSON CHANGE last_name surname VARCHAR;Koda izmaiÅas
MÄs mainÄ«jÄm lauka nosaukumu lastName uz uzvÄrdu.
Kolonnas pÄrdÄvÄÅ”ana atpakaļ saderÄ«gÄ veidÄ
TÄ ir visbiežÄk sastopamÄ situÄcija, ar kuru mÄs varam saskarties. Mums jÄveic atpakaļ nesaderÄ«gas izmaiÅas. MÄs jau esam pierÄdÄ«juÅ”i, ka, lai izvairÄ«tos no dÄ«kstÄves, mums nav jÄpiemÄro datubÄzes migrÄcijas bez papildu darbÄ«bÄm. Å ajÄ raksta sadaÄ¼Ä mÄs veiksim 3 programmatÅ«ras izvietoÅ”anas kopÄ ar datubÄzu migrÄcijÄm, lai sasniegtu vÄlamo rezultÄtu, saglabÄjot atpakaļ saderÄ«bu.
PiezÄ«me. AtgÄdinÄm, ka mums ir DŠ versija
v1. TÄ satur kolonnasfirst_nameunlast_name. Mums jÄmainalast_nameuzuzvÄrdu. Mums arÄ« ir programma versijÄ1.0.0,, kas pagaidÄm neizmantouzvÄrdu.
2. solis: Pievienojam surname
Lietojumprogrammas versija: 2.0.0
Datu bÄzes versija: v2
KomentÄrs
Pievienojot jaunu kolonnu un kopÄjot tÄs saturu, mÄs izveidojam atpakaļ saderÄ«gas DŠ izmaiÅas. TajÄ paÅ”Ä laikÄ, ja mÄs atgriezÄ«sim JAR vai mums bÅ«s strÄdÄjoÅ”s vecais JAR, tas nepiesprÄgs izpildes laikÄ.
Izlaižam jauno versiju
Soli pa solim:
- veiciet DŠ migrÄciju, lai izveidotu jauno kolonnu
uzvÄrdu. Tagad jÅ«su DŠ versijav2 - nokopÄjiet datus no
last_nameparuzvÄrdu. LÅ«dzu, Åemiet vÄrÄ,, ja jums ir daudz Å”o datu, jums jÄpÄrdomÄ partiju migrÄcija! - uzrakstiet kodu, kur tiek izmantots ABI un jauns, un vecais kolonna. Tagad jÅ«su lietojumprogrammas versija
2.0.0 - izlasiet vÄrtÄ«bu no kolonnas
uzvÄrdu, ja tÄ navnull, vai no last_name, jauzvÄrdunav norÄdÄ«ts. JÅ«s varat dzÄstgetLastName()no koda, jo tas atgriezÄ«snullatgriežot jÅ«su lietojumprogrammu ar3.0.0lÄ«dz2.0.0.
Ja jÅ«s izmantojat Spring Boot Flyway, Å”ie divi soļi tiks izpildÄ«ti versijas sÄkumÄ 2.0.0 lietojumprogrammas. Ja jÅ«s manuÄli palaižat datu bÄzes versiju vadÄ«bas rÄ«ku, jums bÅ«s jÄveic divi atseviŔķi soļi (vispirms manuÄli atjauniniet db versiju un pÄc tam izvietojiet jaunu lietojumprogrammu).
SvarÄ«gi. Atcerieties, ka jaunizveidotajai kolonnai NEDRÄŖKST bÅ«t NOT NULL. Ja jÅ«s veicat atgrieÅ”anos, vecÄ lietojumprogramma nezinÄs par jauno kolonnu un neiestatÄ«s to laikÄ
Insert.Bet, ja jÅ«s pievienosiet Å”o ierobežojumu, un jÅ«su DB bÅ«sv2, tas prasÄ«s jauno kolonnas vÄrtÄ«bu iestatīŔanu. Tas radÄ«s ierobežojumu pÄrkÄpumus.SvarÄ«gi. Jums vajadzÄtu izdzÄst metodi
getLastName(), jo versijÄ3.0.0koda konceptÄ nav kolonnaslast_name. Tas nozÄ«mÄ, ka tur tiks iestatÄ«ti null. JÅ«s varat saglabÄt metodi un pievienot pÄrbaudes uznull, bet daudz labÄks risinÄjums bÅ«tu pÄrliecinÄties, ka loÄ£ikÄgetSurname()jÅ«s esat izvÄlÄjuÅ”ies pareizo nenobÄ«doÅ”o vÄrtÄ«bu.
A/B testÄÅ”ana
PaÅ”reizÄjÄ situÄcija ir tÄda, ka mums ir lietojumprogramma versijÄ 1.0.0, izvietota uz produkcijas, un DB ir v1. Mums jÄizvieto otra versijas lietojumprogrammas instance 2.0.0, kas atjaunos datu bÄzi lÄ«dz v2.
Soli pa solim:
- ir izvietots jaunais lietojumprogrammas instants versijÄ
2.0.0, kas atjaunina datu bÄzi lÄ«dzv2 - tajÄ paÅ”Ä laikÄ daži pieprasÄ«jumi tika apstrÄdÄti ar versijas instancÄm
1.0.0 - atjauninÄÅ”ana noritÄja veiksmÄ«gi, un jums ir vairÄkas darbÄ«gas versijas lietojumprogrammas instancÄs
1.0.0un pÄrÄjÄs versijas2.0.0.Visi sazinÄs ar DB, kasv2 - versija
1.0.0neizmanto datu bÄzÄ kolonnas surname, bet versija2.0.0izmanto. ViÅi netraucÄ viens otram, un kļūdÄm nevajadzÄtu bÅ«t. - versija
2.0.0saglabÄ datus gan vecajÄ, gan jaunajÄ kolonnÄ, kas nodroÅ”ina atpakaļsavienojamÄ«bu.
SvarÄ«gi. Ja jums ir kÄdi pieprasÄ«jumi, kas skaita elementus, pamatojoties uz vÄrtÄ«bÄm no vecÄs / jaunÄs kolonnas, jums jÄatceras, ka tagad jums ir duplikÄti vÄrtÄ«bÄs (droÅ”i vien tie joprojÄm migrÄ). PiemÄram, ja vÄlaties saskaitÄ«t lietotÄjus, kuru uzvÄrds (kÄ to sauc) sÄkas ar burtu
A, tad lÄ«dz datu migrÄcijas pabeigÅ”anai (vecÄājaunskolonna) jums var bÅ«t nekonsistenti dati, ja jÅ«s pieprasÄt no jaunÄs kolonnas.
Lietojumprogrammas atgrieŔana
Tagad mums ir versijas lietojumprogrammas 2.0.0 un datu bÄze ir v2.
Soli pa solim:
- atgrieziet savu lietojumprogrammu uz versiju
1.0.0. - versija
1.0.0neizmanto datu bÄzÄ kolonnuuzvÄrdu, tÄpÄc atjaunoÅ”anai jÄbÅ«t veiksmÄ«gai
IzmaiÅas DB
DB satur kolonnu ar nosaukumu last_name.
OriÄ£inÄlais Flyway skripts:
CREATE TABLE PERSON (
id BIGINT GENERATED BY DEFAULT AS IDENTITY,
first_name varchar(255) not null,
last_name varchar(255) not null
);
insert into PERSON (first_name, last_name) values ('Dave', 'Syer');Pievienojuma skripts uzvÄrdu.
UzmanÄ«bu. Atcerieties, ka NAV JÄPIEVIENO nekÄdi ierobežojumi NOT NULL pie pievienotÄs kolonnas. Ja jÅ«s atsaucat JAR, vecÄ versija nezina par pievienoto kolonnu un automÄtiski pieŔķirs tam NULL vÄrtÄ«bu. Ja Å”Äds ierobežojums ir, vecÄ lietotne vienkÄrÅ”i sabruks.
-- PIEZÄŖME: Å ai laukam nevar bÅ«t NOT NULL ierobežojums, jo, ja jÅ«s atgriezÄ«sities, vecÄ versija nezina par Å”o lauku
-- un vienmÄr pieŔķirs tam NULL
ALTER TABLE PERSON ADD surname varchar(255);
-- PIEVÄRSÄŖSIMIES, KA TÄ IR ÄTRA MIGRÄCIJA - CITÄGAD MUMS BÅŖTU JÄMIGRÄ PA Å AJÄS DAÄ»ÄS
UPDATE PERSON SET PERSON.surname = PERSON.last_nameKoda izmaiÅas
MÄs saglabÄjam datus kÄ last_name, tÄ arÄ« uzvÄrdu. TajÄ paÅ”Ä laikÄ lasam no last_name, jo Ŕī kolonna ir visaktuÄlÄka. IzvietoÅ”anas procesÄ daži pieprasÄ«jumi varÄja tikt apstrÄdÄti ar lietotnes instance, kas vÄl nebija atjauninÄta.
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* Reading from the new column if it's set. If not the from the old one.
*
* When migrating from version 1.0.0 -> 2.0.0 this can lead to a possibility that some data in
* the surname column is not up to date (during the migration process lastName could have been updated).
* In this case one can run yet another migration script after all applications have been deployed in the
* new version to ensure that the surname field is updated.
*
* However it makes sense since when looking at the migration from 2.0.0 -> 3.0.0. In 3.0.0 we no longer
* have a notion of lastName at all - so we don't update that column. If we rollback from 3.0.0 -> 2.0.0 if we
* would be reading from lastName, then we would have very old data (since not a single datum was inserted
* to lastName in version 3.0.0).
*/
public String getSurname() {
return this.surname != null ? this.surname : this.lastName;
}
/**
* Storing both FIRST_NAME and SURNAME entries
*/
public void setSurname(String surname) {
this.lastName = surname;
this.surname = surname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", lastName=" + this.lastName + ", surname=" + this.surname
+ "]";
}
}3. solis: no koda noÅemt last_name
Lietojumprogrammas versija: 3.0.0
Datu bÄzes versija:v3
KomentÄrs
PiezÄ«me: AcÄ«mredzot oriÄ£inÄlajÄ rakstÄ autors kļūdaini kopÄjis Ŕī bloka tekstu no 2. soļa. Å ajÄ solÄ« jÄveic izmaiÅas lietotnes kodÄ, kas vÄrstas uz funkcionalitÄtes noÅemÅ”anu, kas izmanto kolonnu last_name.
Pievienojot jaunu kolonnu un kopÄjot tÄs saturu, mÄs radÄ«jÄm uz leju saderÄ«gas izmaiÅas DB. TurklÄt, ja mÄs atsaucam JAR vai mums ir strÄdÄjoÅ”s vecais JAR, tas nesabruks izpildes laikÄ.
Lietojumprogrammas atgrieŔana
Å obrÄ«d mums ir lietotne versijÄ 3.0.0 un datubÄze v3. Versija 3.0.0 neglabÄ datus last_name. Tas nozÄ«mÄ, ka uzvÄrdu satur visjaunÄko informÄciju.
Soli pa solim:
- atgrieziet savu lietojumprogrammu uz versiju
2.0.0. - versija
2.0.0izmanto unlast_nameunuzvÄrdu. - versija
2.0.0paÅemsuzvÄrdu, ja tas nav nulles, citÄdi ālast_name
Datu bÄzes izmaiÅas
DatubÄzÄ nav struktÅ«ras izmaiÅu. Tiek izpildÄ«ts nÄkamais skripts, kas veic veco datu galÄ«go migrÄciju:
-- PIEVÄRSÄŖSIMIES, KA TÄ IR ÄTRA MIGRÄCIJA - CITÄGAD MUMS BÅŖTU JÄMIGRÄ PA Å AJÄS DAÄ»ÄS
-- ARÄŖ MÄS NEKONTROLÄJAM, JA MÄS NEPÄRRAUDAMIES VECOS IERAKSTUS. MUMS BÅŖTU JÄSALÄŖDZINA
-- IERAKSTU VERSIJAS, LAI PÄRLIECINÄTU, KA, JA JAU IR IERAKSTS AR AUGSTÄKU VERSIJAS NUMURU
-- MÄS NEPÄRRAUDAMIES TO.
UPDATE PERSON SET PERSON.surname = PERSON.last_name;
-- NOÅ
EMOT NOT NULL IEROBEŽOJUMU; CITÄGAD TIEM MÄS MÄĶAM IEVADÄT NULL VÄRTÄŖBU LAST_NAME
-- AR NOT NULL IEROBEŽOJUMU.
ALTER TABLE PERSON MODIFY COLUMN last_name varchar(255) NULL DEFAULT NULL;Koda izmaiÅas
PiezÄ«me: Å Ä« bloka apraksts arÄ« tika kļūdaini kopÄts autoram no 2. soļa. SaskaÅÄ ar raksta loÄ£iku, izmaiÅas kodÄ Å”ajÄ solÄ« jÄbÅ«t vÄrstÄm uz elementu noÅemÅ”anu, kas strÄdÄ ar kolonnu last_name.
MÄs glabÄjam datus kÄ last_name, tÄ arÄ« surname. TurklÄt mÄs lasÄm no kolonnas last_name, jo tÄ ir visatbilstoÅ”ÄkÄ. IzvietoÅ”anas procesÄ daži pieprasÄ«jumi var tikt apstrÄdÄti ar instanci, kas vÄl nav atjauninÄta.
/*
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.flyway;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String surname;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getSurname() {
return this.surname;
}
public void setSurname(String lastname) {
this.surname = lastname;
}
@Override
public String toString() {
return "Person [firstName=" + this.firstName + ", surname=" + this.surname
+ "]";
}
}4. solis: DzÄst last_name no DB
Lietojumprogrammas versija: 4.0.0
Datu bÄzes versija: v4
KomentÄrs
TÄ kÄ versijas kods 3.0.0 neizmantot kolonu last_name, izpildes laikÄ nekas slikts nenotiks, ja mÄs atkÄpsimies lÄ«dz 3.0.0 pÄc kolonnas dzÄÅ”anas no datubÄzes.
Izpildes skriptu žurnÄli
MÄs to darÄ«sim Å”ÄdÄ veidÄ:
01) Palaižam 1.0.0
02) GaidÄm, kad lietotne (1.0.0) ieslÄgsies
03) Ä¢enerÄjam personu, izsaucot POST localhost:9991/person uz versiju 1.0.0
04) Palaižam 2.0.0
05) GaidÄm, kad lietotne (2.0.0) ieslÄgsies
06) Ä¢enerÄjam personu, izsaucot POST localhost:9991/person uz versiju 1.0.0
07) Ä¢enerÄjam personu, izsaucot POST localhost:9992/person uz versiju 2.0.0
08) NogalinÄm lietotni (1.0.0)
09) Palaižam 3.0.0
10) GaidÄm, kad lietotne (3.0.0) ieslÄgsies
11) Ä¢enerÄjam personu, izsaucot POST localhost:9992/person uz versiju 2.0.0
12) Ä¢enerÄjam personu, izsaucot POST localhost:9993/person uz versiju 3.0.0
13) NogalinÄm lietotni (3.0.0)
14) Palaižam 4.0.0
15) GaidÄm, kad lietotne (4.0.0) ieslÄgsies
16) Ä¢enerÄjam personu, izsaucot POST localhost:9993/person uz versiju 3.0.0
17) Ä¢enerÄjam personu, izsaucot POST localhost:9994/person uz versiju 4.0.0
SÄkam lietotni versijÄ 1.0.0
Ä¢enerÄjam personu versijÄ 1.0.0
Sūtot post uz 127.0.0.1:9991/person. Šī ir atbilde:
{"firstName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2","lastName":"52b6e125-4a5c-429b-a47a-ef18bbc639d2"}
SÄkam lietotni versijÄ 2.0.0
Ä¢enerÄjam personu versijÄ 1.0.0
Sūtot post uz 127.0.0.1:9991/person. Šī ir atbilde:
{"firstName":"e41ee756-4fa7-4737-b832-e28827a00deb","lastName":"e41ee756-4fa7-4737-b832-e28827a00deb"}
Ä¢enerÄjam personu versijÄ 2.0.0
Sūtot post uz 127.0.0.1:9992/person. Šī ir atbilde:
{"firstName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","lastName":"0c1240f5-649a-4bc5-8aa9-cff855f3927f","surname":"0c1240f5-649a-4bc5-8aa9-cff855f3927f"}
NogalinÄm lietotni 1.0.0
SÄkam lietotni versijÄ 3.0.0
Ä¢enerÄjam personu versijÄ 2.0.0
Sūtot post uz 127.0.0.1:9992/person. Šī ir atbilde:
{"firstName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","lastName":"74d84a9e-5f44-43b8-907c-148c6d26a71b","surname":"74d84a9e-5f44-43b8-907c-148c6d26a71b"}
Ä¢enerÄjam personu versijÄ 3.0.0
Sūtot post uz 127.0.0.1:9993/person. Šī ir atbilde:
{"firstName":"c6564dbe-9ab5-40ae-9077-8ae6668d5862","surname":"c6564dbe-9ab5-40ae-9077-8ae6668d5862"}
NogalinÄm lietotni 2.0.0
SÄkam lietotni versijÄ 4.0.0
Ä¢enerÄjam personu versijÄ 3.0.0
Sūtot post uz 127.0.0.1:9993/person. Šī ir atbilde:
{"firstName":"cbe942fc-832e-45e9-a838-0fae25c10a51","surname":"cbe942fc-832e-45e9-a838-0fae25c10a51"}
Ä¢enerÄjam personu versijÄ 4.0.0
Sūtot post uz 127.0.0.1:9994/person. Šī ir atbilde:
{"firstName":"ff6857ce-9c41-413a-863e-358e2719bf88","surname":"ff6857ce-9c41-413a-863e-358e2719bf88"}IzmaiÅas DB
AttiecÄ«bÄ uz v3 mÄs vienkÄrÅ”i dzÄÅ”am kolonnu last_name un pievienojam trÅ«kstoÅ”os ierobežojumus.
-- DZEST KOLONU
ALTER TABLE PERSON DROP last_name;
-- PIEVIENOT IEROBEŽOJUMUS
UPDATE PERSON SET surname='' WHERE surname IS NULL;
ALTER TABLE PERSON ALTER COLUMN surname VARCHAR NOT NULL;Koda izmaiÅas
IzmaiÅas kodÄ nav.
Izvade
MÄs veiksmÄ«gi pielÄgojÄm atpakaļ nesaderÄ«gu kolonnas nosaukuma izmaiÅu, veicot vairÄkus atpakaļ saderÄ«gus izvietojumus. ZemÄk ir veikto darbÄ«bu kopsavilkums:
- izvietojums lietotnes versija
1.0.0arv1DB shÄma (kolonnas nosaukums =last_name) - izvietojums lietotnes versija
2.0.0,kas saglabÄ datuslast_nameunuzvÄrdu. Lietotne lasa nolast_name. DB atrodas versijÄv2, kas satur kolonnas kÄlast_name, ganuzvÄrds. uzvÄrdsir kopija last_name. (PiezÄ«me: Å”im laukam nedrÄ«kst bÅ«t ierobežojums not null) - izvietojums lietotnes versija
3.0.0, kas saglabÄ datus tikaiuzvÄrduun lasa no uzvÄrda. AttiecÄ«bÄ uz DB notiek pÄdÄjÄ migrÄcijalast_nameparuzvÄrdu. ArÄ« ierobežojums NOT NULL tiek noÅemts nolast_name. DB paÅ”laik ir versijÄv3 - izvietojums lietotnes versija
4.0.0ā kodÄ netiek izdarÄ«tas nekÄdas izmaiÅas. DatubÄzes izvietoÅ”anav4, kas dzÄÅ”last_name. Å eit jÅ«s varat pievienot jebkÄdus trÅ«kstoÅ”os ierobežojumus DB.
Izmantojot Å”o pieeju, jÅ«s vienmÄr varat atgriezties uz vienu versiju atpakaļ, nesabojÄjot datu bÄzes / lietotnes saderÄ«bu.
Kods
Visi kods, kas izmantots Å”ajÄ rakstÄ, ir pieejams . ZemÄk ir papildu apraksts.
Projektu
PÄc repozitorija klonÄÅ”anas jÅ«s redzÄsiet sekojoÅ”o mapju struktÅ«ru.
āāā boot-flyway-v1 - 1.0.0 versija lietotnei ar v1 shÄmu
āāā boot-flyway-v2 - 2.0.0 versija lietotnei ar v2 shÄmu (atpakaļsaderÄ«ga - lietotni var atgriezt)
āāā boot-flyway-v2-bad - 2.0.0.BAD versija lietotnei ar v2bad shÄmu (neatpakaļsaderÄ«ga - lietotni nevar atgriezt)
āāā boot-flyway-v3 - 3.0.0 versija lietotnei ar v3 shÄmu (lietotni var atgriezt)
āāā boot-flyway-v4 - 4.0.0 versija lietotnei ar v4 shÄmu (lietotni var atgriezt)Skripti
JÅ«s varat palaist scenÄrijus, kas aprakstÄ«ti zemÄk esoÅ”ajos skriptos, kas demonstrÄjot atpakaļ saderÄ«gas un nesaderÄ«gas izmaiÅas DB.
Lai redzÄtu gadÄ«jumu ar atpakaļ saderÄ«gÄm izmaiÅÄm, palaižiet:
.\/scripts\/scenario_backward_compatible.shUn lai redzÄtu gadÄ«jumu ar atpakaļ nesaderÄ«gÄm izmaiÅÄm, palaižiet:
.\/scripts\/scenario_backward_incompatible.shSpring Boot Sample Flyway
Visi piemÄri Åemti no Spring Boot Sample Flyway.
Jūs varat aplūkot http://localhost:8080/flyway, tur ir skriptu saraksts.
Å is piemÄrs arÄ« iekļauj H2 konsoli (adresÄ http://localhost:8080/h2-console), lai jÅ«s varÄtu apskatÄ«t datu bÄzes stÄvokli (noklusÄjuma jdbc URL ā jdbc:h2:mem:testdb).
Papildus
Izlasiet arÄ« citus rakstus mÅ«su emuÄrÄ:
Avots: habr.com
