Skip to content

Commit

Permalink
improve consistency and translations (heroku#339)
Browse files Browse the repository at this point in the history
Co-authored-by: Johnathan Lyman <[email protected]>
  • Loading branch information
DanielKucal and johlym committed Jan 4, 2024
1 parent e741468 commit 5d8ee45
Show file tree
Hide file tree
Showing 7 changed files with 15 additions and 15 deletions.
4 changes: 2 additions & 2 deletions content/pl/build-release-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@

![Kod staje się buildem, jeśli zostanie połączony z konfiguracją by stworzyć release](/images/release.png)

**Aplikacja 12factor ściśle rozgranicza etapy budowy, publikacji i uruchomiania** Kiedy aplikacja została już uruchomiona, nie można zmienić jej kodu w inny sposób niż zbudować ją na nowo na podstawie wcześniej naniesionych zmian.
**Aplikacja 12factor ściśle rozgranicza etapy budowy, publikacji i uruchamiania.** Kiedy aplikacja została już uruchomiona, nie można zmienić jej kodu w inny sposób niż zbudować ją na nowo na podstawie wcześniej naniesionych zmian.

Narzędzia do obsługi wdrożeń zazwyczaj oferują moduły do zarządzania releasami, w tym możliwość do powrotu do poprzedniej wersji (rollback). Np. narzędzie [Capistrano](https://github.com/capistrano/capistrano/wiki) przechowuje releasy w podkatalogu `releases`, gdzie obecna wersja opublikowanej aplikacji jest symlinkowana do jednej z wersji przechowywanej w katalogu Capistrano. Komenda `rollback` pozwala na szybką zmianę wersji opublikowanej aplikacji na jedną z poprzednich.

Każdy release powinien zawsze posiadać unikalny identyfikator, jak np. data publikacji aplikacji (taka jak `2011-04-06-20:32:17`) lub inkrementowany numer (np. `v100`). Do rejestru opublikowanych wersji aplikacji można jedynie dodawać jej nowe wersje, jego zawartość nie może być zmieniana w żaden inny sposób.

Aplikacja może zostać zbudowana gdy developer zdecyduje o wdrożeniu zmian do kodu. Uruchomienie aplikacji może natomiast nastąpić automatycznie po restarcie serwera lub jednego z procesów aplikacji po błędzie krytycznym. Dlatego też etap uruchamiania aplikacji powinien być jak najbardziej jednolity minimalizując równocześnie ryzyko wystąpienia problemów ze startem aplikacji - mogą one spowodować zaprzestanie działania aplikacji np. w nocy, kiedy to nie ma żadnego developera "pod ręką". Etap budowy aplikacji może być bardziej złożony, ponieważ ewentualne błędy są zawsze widoczne dla developera, który nadzoruje ten proces.
Aplikacja może zostać zbudowana, gdy developer zdecyduje o wdrożeniu zmian do kodu. Uruchomienie aplikacji może natomiast nastąpić automatycznie po restarcie serwera lub jednego z procesów aplikacji po błędzie krytycznym. Dlatego też etap uruchamiania aplikacji powinien być jak najbardziej jednolity minimalizując równocześnie ryzyko wystąpienia problemów ze startem aplikacji - mogą one spowodować zaprzestanie działania aplikacji np. w nocy, kiedy to nie ma żadnego developera "pod ręką". Etap budowy aplikacji może być bardziej złożony, ponieważ ewentualne błędy są zawsze widoczne dla developera, który nadzoruje ten proces.
2 changes: 1 addition & 1 deletion content/pl/concurrency.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Każdy program komputerowy od momentu uruchomienia jest reprezentowany przez jed

![Skala wyrażana jest przez działające procesy, natomiast różnorodność obciążenia wyrażana jest w typach procesów](/images/process-types.png)

**W aplikacji 12factor, procesy są typem pierwszoklasowym** Zachowanie tych procesów jest mocno wzorowane na [modelu procesów unixowych dla usług działających w wewnątrz systemu operacyjnego](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Używając tego modelu programista może zaprojektować aplikację by radziła sobie z różnorodnym obciążeniem przez przypisywanie każdej czynności do *typu procesu*. Przykłady to m.in obsługa procesów sieciowych przez HTTP oraz długotrwałe działanie zadań w tle opierających się na procesach roboczych.
**W aplikacji 12factor, procesy są typem pierwszoklasowym.** Zachowanie tych procesów jest mocno wzorowane na [modelu procesów unixowych dla usług działających w wewnątrz systemu operacyjnego](https://adam.herokuapp.com/past/2011/5/9/applying_the_unix_process_model_to_web_apps/). Używając tego modelu programista może zaprojektować aplikację by radziła sobie z różnorodnym obciążeniem przez przypisywanie każdej czynności do *typu procesu*. Przykłady to m.in obsługa procesów sieciowych przez HTTP oraz długotrwałe działanie zadań w tle opierających się na procesach roboczych.

Mimo tego procesy wciąż mogą się zwielokrotnić przez wątki w środowisku maszyny wirtualnej lub w asynchronicznym modelu wydarzeń, którego implementację możemy znaleźć wśród narzędzi takich jak [EventMachine](https://github.com/eventmachine/eventmachine), [Twisted](https://twistedmatrix.com/trac/), albo [Node.js](https://nodejs.org/). Należy pamiętać, że pojedyncza maszyna wirtualna może z czasem wymagać coraz więcej zasobów (skala pionowa), dlatego aplikacja musi być również w stanie pracować w oparciu o wiele procesów działających na wielu fizycznych maszynach.

Expand Down
2 changes: 1 addition & 1 deletion content/pl/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ Innym podejściem do konfiguacji jest korzystanie z plików, które nie znajduj

Kolejnym zagadnieniem zarządzania konfiguracją jest jej grupowanie. Czasem aplikacje gromadzą konfigurację w grupach (czasem nazywane "środowiskami") nazywanych od nazwy wdrożenia, takie jak `development`, `test`, czy `produkcja` w Railsach. Ten sposób organizacji jest niestety nieskalowalny. Im więcej różnych wdrożeń, tym większa potrzeba nazw, jak np. `staging` czy `qa`. Wraz z rozwojem projektu programiści mogą dodawać swoje specjalne konfiguracje, jak `staging-józefa`. Efektem tego mogą być niezliczone kombinacje nazw plików konfiguracyjnych, co utrudniać będzie zarządzanie wdrożonymi aplikacji.

W aplikacji 12factor zmienne środowiskowe służą do precyzyjnej kontroli poszczególnych ustawień, posiadając różne, nie mylące się ze sobą nazwy. Nigdy nie są zgrupowane w "środowiskach", tylko niezależnie ustawiane dla każdego wdrożenia. Taki model konfiguracji skaluje się bez problemu, nawet jeśli aplikacja będzie potrzebowała w przyszłości więcej zróżnicowanych wdrożeń.
W aplikacji 12factor zmienne środowiskowe służą do precyzyjnej kontroli poszczególnych ustawień, posiadając różne, niemylące się ze sobą nazwy. Nigdy nie są zgrupowane w "środowiskach", tylko niezależnie ustawiane dla każdego wdrożenia. Taki model konfiguracji skaluje się bez problemu, nawet jeśli aplikacja będzie potrzebowała w przyszłości więcej zróżnicowanych wdrożeń.
6 changes: 3 additions & 3 deletions content/pl/dev-prod-parity.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Z doświadczenia wiadomo, że od zawsze istniały różnice pomiędzy środowiskiem developerskim (developer pracujący nad swoją lokalną wersją [kodu](./codebase) aplikacji) a produkcyjnym (działająca aplikacja dostępna dla użytkowników. Ze względu na ich charakter, możemy wymienić trzy rodzaje różnic:

* **Różnica czasowa:** Developer może pracować nad kodem przez dni, tygodnie, miesiące zanim ostatecznie pojawi się on w wersji produkcyjnej.
* **Różnica odpowiedzialności**: Developer tworzy kod aplikacji, natomiast kto inny wdraża go do na produkcję.
* **Różnica odpowiedzialności**: Developer tworzy kod aplikacji, natomiast kto inny wdraża go na produkcję.
* **Różnica narzędzi**: Developer może używać narzędzi takich jak Nginx, SQLite i systemu OS X, natomiast wersja produkcyjna będzie opierać się na Apache, MySQL i systemie Linux.

**Aplikacja 12factor jest zaprojektowana tak by można ją było [bez przerwy wdrażać na produkcję](https://avc.com/2011/02/continuous-deployment/) minimalizując różnice pomiędzy środowiskami.** Mając na uwadze powyższe różnice, można sobie z nimi radzić na różne sposoby:
Expand Down Expand Up @@ -67,9 +67,9 @@ Zachowanie podobieństw między wdrożeniami jest ważne w przypadku [usług wsp
</tr>
</table>

Czasami zdarza się, że developerzy w swoim lokalnym środowisku wolą korzystać z "lżejszych" wersji różnych usług, na produkcji natomiast używając bardziej zaawansowanych narzędzi. Przykładem takiej sytuacji jest używanie lokalnie SQLite, a PostgreSQL na produkcji. Podobnie wygląda też użycie na środowisku developerskim do cachowania pamięci, zamiast Memcached znajdującego się na produkcji.
Czasami zdarza się, że developerzy w swoim lokalnym środowisku wolą korzystać z "lżejszych" wersji różnych usług, na produkcji natomiast używając bardziej zaawansowanych narzędzi. Przykładem takiej sytuacji jest używanie lokalnie SQLite, a PostgreSQL na produkcji. Podobnie wygląda też użycie pamięci podręcznej procesu na środowisku developerskim do cachowania pamięci, zamiast Memcached znajdującego się na produkcji.

**Developer postępujący zgodnie zasadami 12factor opiera się pokusie używania usług różniących się pomiędzy środowiskami**, nawet wtedy, gdy adaptery teoretycznie ukrywają różnice w implementacji pod warstwą abstrakcji. Z powodu różnic pomiędzy usługami wspierającymi mogą pojawić się niezgodności, powodując, że kod, który działał i był testowany lokalnie lub na stagingu, przestanie funkcjonować na produkcji. Pojawianie się tego typu błędów negatywnie wpływa na proces ciągłego wdrażania aplikacji. Czas stracony na wykrywaniu takich błędów i konsekwentnych awariach podczas wdrażania aplikacji może sporo kosztować, zwłaszcza gdy podobne problemy będą się z czasem gromadzić.
**Developer postępujący zgodnie zasadami 12factor opiera się pokusie używania usług różniących się pomiędzy środowiskami**, nawet wtedy, gdy adaptery teoretycznie ukrywają różnice w implementacji pod warstwą abstrakcji. Z powodu różnic pomiędzy usługami wspierającymi mogą pojawić się niezgodności, powodując, że kod, który działał i był testowany lokalnie lub na stagingu, przestanie funkcjonować na produkcji. Pojawianie się tego typu błędów negatywnie wpływa na proces ciągłego wdrażania aplikacji. Czas stracony na wykrywaniu takich błędów i w konsekwencji awarii podczas wdrażania aplikacji może sporo kosztować, zwłaszcza gdy podobne problemy będą się z czasem gromadzić.

Lekkie wersje usług w obecnych czasach nie są już tak atrakcyjne jak kiedyś. Nowoczesne usługi takie jak Memcached, PostgreSQL oraz RabbitMQ nie są trudne do instalacji w lokalnym środowisku, dzięki narzędziom jak [Homebrew](https://mxcl.github.com/homebrew/) i [apt-get](https://help.ubuntu.com/community/AptGet/Howto). Innym rozwiązaniem są narzędzia do deklaratywnego [provisioningu](https://en.wikipedia.org/wiki/Provisioning) takie jak [Chef](https://www.opscode.com/chef/) czy [Puppet](https://docs.puppetlabs.com/) połączone z lekkimi środowiskami wirtualnymi jak np. [Vagrant](https://vagrantup.com/). Pozwala ono developerom na uruchamianie lokalnych środowisk, które są bardzo zbliżone do produkcyjnych. Koszt instalacji i używania takich rozwiązań jest stosunkowo niski, biorąc pod uwagę korzyści płynące z utrzymywania jednolitych środowisk i procesu ciągłego wdrażania aplikacji.

Expand Down
8 changes: 4 additions & 4 deletions content/pl/disposability.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
## IX. Zbywalność
### Zwiększ elastyczność aplikacji przez szybki start i bezproblemowe zamknięcie

**[Procesy](./processes) aplikacji 12factor są *jednorazowe*, znaczy to, że mogą być wystartowane lub zatrzymane w dowolnym momencie.** Ułatwia to elastyczne skalowanie i szybkie wdrożenia [kodu](./codebase), zmianę [konfiguracji](./config) oraz zapewnia większą stabilność przy wdrożeniu na produkcję.
**[Procesy](./processes) aplikacji 12factor są *jednorazowe*, znaczy to, że mogą być wystartowane lub zatrzymane w dowolnym momencie.** Ułatwia to elastyczne skalowanie i szybkie wdrożenia [kodu](./codebase), zmianę [konfiguracji](./config) oraz zapewnia większą stabilność wdrożeń produkcyjnych.

Procesy powinny dążyć do **minimalizowania czasu swojego rozruchu**. W idealnej sytuacji proces powinien potrzebować kilku sekund na to aby wystartować i być gotowym na przyjmowanie zapytań. Dzięki krótkiemu czasowi startu można szybciej wykonywać kolejne [wdrożenia](./build-release-run) oraz łatwiej skalować aplikację. Zwiększa to również zdolności aplikacji do radzenia sobie z problemami, ponieważ `process manager` może bezproblemowo przenieść je na nową maszynę fizyczną, gdy zajdzie taka potrzeba.
Procesy powinny dążyć do **minimalizowania czasu swojego rozruchu**. W idealnej sytuacji proces powinien potrzebować kilku sekund na to aby wystartować i być gotowym na przyjmowanie zapytań. Dzięki krótkiemu czasowi startu można szybciej wykonywać kolejne [wdrożenia](./build-release-run) oraz łatwiej skalować aplikację. Zwiększa to również zdolność aplikacji do radzenia sobie z problemami, ponieważ `process manager` może bezproblemowo przenieść je na nową maszynę fizyczną, gdy zajdzie taka potrzeba.

Procesy **zamykają się gdy otrzymają sygnał [SIGTERM](https://en.wikipedia.org/wiki/SIGTERM)** od managera procesów. Dla procesów sieciowych poprawne zamknięcie polega na zakończeniu nasłuchiwania na porcie usługi (skutkiem czego jest odrzucanie nowych zapytań), zakończenie obecnych, a ostatecznie zaprzestaniu działania. Wynika z tego, że zapytania HTTP są krótkie (trwają nie więcej niż kilka sekund), lub w przypadku `long pollingu` i utraty połączenia klient powinien bezproblemowo spróbować połączyć się ponownie.
Procesy **zamykają się gdy otrzymają sygnał [SIGTERM](https://en.wikipedia.org/wiki/SIGTERM)** od managera procesów. Dla procesów sieciowych poprawne zamknięcie polega na zakończeniu nasłuchiwania na porcie usługi (skutkiem czego jest odrzucanie nowych zapytań), zakończenie obecnych, a ostatecznie zaprzestaniu działania. Ten model zakłada, że zapytania HTTP są krótkie (trwają nie więcej niż kilka sekund), lub w przypadku `long pollingu` i utraty połączenia klient powinien bezproblemowo spróbować połączyć się ponownie.

Dla procesów roboczych poprawnym zamknięciem jest zwrot obecnie wykonywanego zadania do kolejki. Dla przykładu w [RabbitMQ](https://www.rabbitmq.com/) działający proces może wysłać wiadomość [`NACK`](https://www.rabbitmq.com/amqp-0-9-1-quickref.html#basic.nack); w [Beanstalkd](https://beanstalkd.github.io), zadanie jest zwracane do kolejki automatycznie, gdy tylko proces się rozłączy. Systemy bazujące na blokadach zasobów jak [Delayed Job](https://github.com/collectiveidea/delayed_job#readme) muszą upewnić się, że odblokowały zajmowany wcześniej zasób. W tym modelu ważne jest to, że wszystkie zadania są [wielobieżne](https://pl.wikipedia.org/wiki/Wielobieżność), co zazwyczaj jest osiągane przez zebranie wyników w transakcję lub uczynienie operacji [idempotentną](https://pl.wikipedia.org/wiki/Idempotentno%C5%9B%C4%87).

Architektura aplikacji 12factor jest również zaprojektowana by działające procesy zostały poprawnie **zakończone w razie awarii** sprzętu. Podczas gdy taka sytuacja jest o wiele rzadsza niż otrzymanie sygnału `SIGTERM`, wciąż może mieć miejsce. Zalecanym podejściem w takich przypadkach jest stosowanie serwerowego systemu kolejkowania zadań, jak Beanstalkd, który zwróci zadanie do kolejki, gdy klient się rozłączy, bądź minie maksymalny czas obsługi pojedynczego zapytania. Architektura ["crash-only"](https://lwn.net/Articles/191059/) jest więc rozwinięciem takiego [konceptu](https://docs.couchdb.org/en/latest/intro/overview.html).
Architektura aplikacji 12factor jest również zaprojektowana tak, by działające procesy zostały poprawnie **zakończone w razie awarii** sprzętu. Podczas gdy taka sytuacja jest o wiele rzadsza niż otrzymanie sygnału `SIGTERM`, wciąż może mieć miejsce. Zalecanym podejściem w takich przypadkach jest stosowanie serwerowego systemu kolejkowania zadań, jak Beanstalkd, który zwróci zadanie do kolejki, gdy klient się rozłączy, bądź minie maksymalny czas obsługi pojedynczego zapytania. Architektura ["crash-only"](https://lwn.net/Articles/191059/) jest więc rozwinięciem takiego [konceptu](https://docs.couchdb.org/en/latest/intro/overview.html).


2 changes: 1 addition & 1 deletion content/pl/port-binding.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ Kwestię obsługi takich zapytań można rozwiązać dodając bibliotekę webser

HTTP nie jest jedyną usługą, którą możną eksportować przez przydzielenie portu. Niemal każdy rodzaj oprogramowania serwerowego może być uruchomiony przez przydzielenie portu na którym jest uruchomiony proces i oczekiwać na przychodzące zapytania. Do przykładów należą [ejabberd](https://www.ejabberd.im/) (komunikujący się przez [XMPP](https://xmpp.org/)), oraz [Redis](https://redis.io/) (komunikujący się przez [Redis protocol](https://redis.io/topics/protocol)).

Warto również zauważyć, że przez przydzielnie portu aplikacja może pełnić funkcję [usługi wspierającej](./backing-services) dla innej aplikacji przez udostępnienie swojego adresu URL jako adres zasobu w [konfiguracji](./config) tejże aplikacji.
Warto również zauważyć, że przez przydzielenie portu aplikacja może pełnić funkcję [usługi wspierającej](./backing-services) dla innej aplikacji przez udostępnienie swojego adresu URL jako adres zasobu w [konfiguracji](./config) tejże aplikacji.
Loading

0 comments on commit 5d8ee45

Please sign in to comment.