100% found this document useful (2 votes)
354 views

Instant Download gRPC Microservices in Go (MEAP V08) Hüseyin Babal PDF All Chapters

Go

Uploaded by

bajadojmili
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
354 views

Instant Download gRPC Microservices in Go (MEAP V08) Hüseyin Babal PDF All Chapters

Go

Uploaded by

bajadojmili
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 65

Download Full Version ebook - Visit ebookmeta.

com

gRPC Microservices in Go (MEAP V08) Hüseyin Babal

https://ebookmeta.com/product/grpc-microservices-in-go-
meap-v08-huseyin-babal/

OR CLICK HERE

DOWLOAD NOW

Discover More Ebook - Explore Now at ebookmeta.com


Instant digital products (PDF, ePub, MOBI) ready for you
Download now and discover formats that fit your needs...

Start reading on any device today!

Shipping Go: Develop, deliver, discuss, design, and go


again (MEAP V08) Joel Holmes

https://ebookmeta.com/product/shipping-go-develop-deliver-discuss-
design-and-go-again-meap-v08-joel-holmes/

ebookmeta.com

Advent of Go Microservices Tit Petric

https://ebookmeta.com/product/advent-of-go-microservices-tit-petric/

ebookmeta.com

Go H ck Yourself 1st Edition Bryson Payne

https://ebookmeta.com/product/go-h-ck-yourself-1st-edition-bryson-
payne/

ebookmeta.com

The Engaged Scholar Expanding the Impact of Acedemic


Research in Today s World 1st Edition Andrew J. Hoffman

https://ebookmeta.com/product/the-engaged-scholar-expanding-the-
impact-of-acedemic-research-in-today-s-world-1st-edition-andrew-j-
hoffman/
ebookmeta.com
Decadence A Very Short Introduction David Weir

https://ebookmeta.com/product/decadence-a-very-short-introduction-
david-weir/

ebookmeta.com

Dynamics in Logistics Twenty Five Years of


Interdisciplinary Logistics Research in Bremen Germany 1st
Edition Michael Freitag
https://ebookmeta.com/product/dynamics-in-logistics-twenty-five-years-
of-interdisciplinary-logistics-research-in-bremen-germany-1st-edition-
michael-freitag/
ebookmeta.com

1000 Questions 1000 Answers B2 2020 Clean 2020th Edition


Némethné Hock Ildikó

https://ebookmeta.com/product/1000-questions-1000-answers-b2-2020-
clean-2020th-edition-nemethne-hock-ildiko/

ebookmeta.com

Bulk Metallic Glasses and Their Composites 2nd Edition


Muhammad Musaddique Ali Rafique

https://ebookmeta.com/product/bulk-metallic-glasses-and-their-
composites-2nd-edition-muhammad-musaddique-ali-rafique/

ebookmeta.com

High-Stakes Cowboy (WEST Protection #0.5) 1st Edition Em


Petrova

https://ebookmeta.com/product/high-stakes-cowboy-west-
protection-0-5-1st-edition-em-petrova/

ebookmeta.com
Are We Really Better Together An Evangelical Perspective
on the Division in The UMC Walter Fenton Rob Renfroe

https://ebookmeta.com/product/are-we-really-better-together-an-
evangelical-perspective-on-the-division-in-the-umc-walter-fenton-rob-
renfroe/
ebookmeta.com
gRPC Microservices in Go MEAP V08
1. Copyright_2023_Manning_Publications
2. welcome
3. 1_Introduction_to_Go_gRPC_Microservices
4. 2_gRPC_Meets_with_Microservices
5. 3_Getting_up_and_running_with_gRPC_and_Golang
6. 4_Microservices_Project_Setup
7. 5_Inter-service_Communication
8. 6_Resilient_Communication
9. 7_Testing_Microservices
10. 8_Deployment
11. 9_Observability
MEAP Edition Manning Early Access Program gRPC Microservices in Go
Version 8

Copyright 2023 Manning Publications


©Manning Publications Co. We welcome reader comments about anything in
the manuscript - other than typos and other simple mistakes. These will be
cleaned up during production of the book by copyeditors and proofreaders.
https://livebook.manning.com/#!/book/grpc-microservices-in-go/discussion

For more information on this and other Manning titles go to

manning.com
welcome
Thank you for purchasing the MEAP Edition of gRPC Microservice in Go.

Microservice Architecture is very popular nowadays because it allows you to


implement independent services with their own software development
lifecycles. Those independent services also help you to build scalable teams
that are responsible for specific business capabilities.

Microservice architecture comes with its own challenges since we end up


building a distributed system product where services communicate with each
other over the network. gRPC helps us to set up hassle free communication
patterns, especially for message exchange during inter-service
communication.

In this book, we deep dive into the theory of Microservice Architecture and
how it is different from Monolithic Architecture. We also use gRPC and Go
to communicate between services with a simple message and rpc definitions.
Besides step by step implementation of each service, you can also see CI/CD
examples applied to Microservice development. Code examples are enriched
with illustrative diagrams to show you the big picture.

We hope you enjoy the book while reading theoretical information with
detailed examples and applying code samples to implement a real
eCommerce application with Microservice Architecture.

We encourage you to ask any question or provide feedback about live book
content in the Livebook Discussion Forum.

–Hüseyin Babal

In this book

Copyright 2023 Manning Publications welcome brief contents 1 Introduction


to Go gRPC Microservices 2 gRPC Meets with Microservices 3 Getting up
and running with gRPC and Golang 4 Microservices Project Setup 5 Inter-
service Communication 6 Resilient Communication 7 Testing Microservices
8 Deployment 9 Observability
1 Introduction to Go gRPC
Microservices
This chapter covers
Introducing Go gRPC Microservices
Comparing gRPC with REST
Understanding when to use gRPC
A better understanding of gRPC microservices with production-grade
use-cases

Good architecture design and proper technology selection help you a lot to
build a high-quality product by eliminating repetitive work and providing the
best toolkit for software development and maintenance. While one of the
main advantages of Microservice Architecture is that it can be implemented
in any language, Go is particularly suited for building high-performance
Cloud-Native distributed applications like Microservices in Kubernetes at a
big scale. Microservices with gRPC communication have already enabled
many companies to implement their products with small services based on
their business capabilities and let those services communicate smoothly with
each other and the public. With the help of Go, the distribution of those
services becomes easier due to its fast compilation, ability to generate
executable binaries, and many other reasons that we will see in detail with
real-life examples in the upcoming chapters.

gRPC is an open-source Remote Procedure Call framework initially


developed by Google in 2015 that helps you to connect services with built-in
support for load balancing, tracing, fault tolerance, and security. The main
power of this framework comes from being able to generate server and client
stubs (object on the client side that implements the same methods as the
service) for multiple languages that you can use in your consumer project to
call remote service methods and in your server project to define business
logic behind those service methods.
Microservice architecture is another form of service-oriented architecture that
defines applications as loosely coupled, fine-grained services that can be
implemented, deployed, and scaled independently.

The main goal of this book is to provide production-grade best practices for
gRPC Microservices so that by the end of this book, you will have the self-
confidence to implement the entire system on your own.

1.1 Benefits of gRPC Microservices


Within a typical monolithic application, calling different business activities
like calling payment service from checkout service means accessing a class
method in a separate module which is very easy. If you use microservices,
such calls will be converted to network communication. It can be a TCP,
HTTP, or event queue call to exchange data between services. Handling
network calls are more challenging than calling another class method, which
can be handled with a simple error-handling mechanism like try-catch blocks.
Even Monoliths are easy to use at first, you may need to decompose that for
several reasons, including slow deployments and inefficient resource
utilization that affects feature development and product maintenance. This
does not mean Monoliths are bad and Microservices are good; on the
contrary, Microservices bring challenges that we will see in detail in Chapter
2. With the help of gRPC, most of the challenges in Microservices, like
handling network failures and applying TLS (Transport Layer Security) to
service communications (that you can see in Chapter 6 in detail), can be
eliminated. Using those built-in features in gRPC, you can improve both
reliability of the product and the productivity of an entire team by using Go
Microservices.

1.1.1 Performance
gRPC provides better performance and security than other protocols like
REST with JSON or XML communication as it uses Protocol Buffers, and
HTTP/2 over TLS is straightforward. Protocol Buffers, also known as
Protobuf, is a language and platform-neutral mechanism for serializing
structural data, which you will see in detail in Chapter 3. This mechanism
empowers gRPC to quickly serialize messages into small and compact
messages on both the server and client sides. In the same way, HTTP/2
enables the performance with server-side push, multiplexing, and header
compression, which we will see in more detail in Chapter 5.

1.1.2 Code Generation & Interoperability


Let's say you have Checkout Service and Payment Service where a customer
can check out a basket which triggers a Payment Service call to pay for the
products in the basket. To access Payment Service, you need to have request
and response models in some place, like a shared library, to access them
easily. Reusing a shared request and response model seems handy in
Microservices, but it is not a good practice, especially if you are using
different languages for each microservices. Duplicating models in Checkout
Service, typically creating another data class to build request object and
deserialize response object into, is a better choice. This is all about preventing
a wrong abstraction, as you may already heard the statement, “A little
duplication is far cheaper than wrong abstraction”
(https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction). There is an
easier way: choose gRPC to define your messages and generate client stubs
so that you can inject this dependency and use it directly in whatever
language you prefer. We will dive deep into code generation in Chapter 3.

gRPC tools and libraries are compatible to work with multiple platforms and
languages, including Go, Java, Python, Ruby, Javascript, C#, and more. The
Protobuf binary wire format, data format as it travels on a wire like in a
network, and well-designed code generation for almost all platforms enables
developers to build performance-critical applications while keeping cross-
platform support. We will see the details of why Protobuf performs well in
inter-service communication in Chapter 3.

gRPC is getting more popular (https://star-history.com/#grpc/grpc&Date)


since you can quickly generate client stubs to provide an SDK of your
services within different languages. You only need to decide what kind of
business objects you need to have. Once you choose which fields you need
for a Checkout model, you can introduce respective request and response
messages. Remember that those messages are just definitions, called IDL
(Interface Definition Language), independent from any language
specification. After you define your message specifications, you can generate
language-specific implementations so that any consumer can depend on that
source. This also means that the development language on the server side can
be different on the client side since server-side methods can be generated as
stubs on the client side for specific languages supported by gRPC.

Besides business objects, you can define service methods and generate
implementations similarly. Those service functions can be called after you
initialize the gRPC client on the consumer side; again, this client is generated
out of the box.

1.1.3 Fault Tolerance


Fault tolerance is the ability of a system to continue operating despite system
failures. An idempotent operation has no additional effect, even if called
more than once. Idempotency is key to a successful fault-tolerant
environment since you need to be sure that, once you retry an operation with
the same parameters in case of failure or not having an expected state, it
shouldn’t change the content of the actual resource. For example, we may
want to retry a user delete operation in case of network failure on response. If
the operation returns the same result even if you call it more than once, we
say this operation is idempotent.

If an operation is not a good fit for the idempotency use case, you must
provide proper validation errors in a response message that helps you know
when to stop the retry operation. Once you guarantee this idempotency or
proper validation, it is just a definition of retry policy on the gRPC side. Fault
tolerance also focuses on topics like Rate Limiting, Circuit Breaker, and Fault
Injection, which we will see in greater detail in Chapter 6.

1.1.4 Security
In most systems, you may need a security layer to protect your product
against unverified sources. gRPC encourages HTTP/2 over SSL/TLS to
authenticate and encrypt exchanged data between client and server. More
specifically, you can easily set that authentication system up by using
SSL/TLS, ALTS (Application Layer Transport Security), or Token Based
Authentication System, which we will cover in more detail in Chapter 6.

1.1.5 Streaming

Sometimes you may need to divide response data into several chunks to
provide them to the user in a paginated way to reduce bandwidth and return
them to the user quickly. Moreover, if they are only interested in specific
pages, it is not meaningful to return all the data simultaneously. In gRPC,
besides the pagination, you can also stream this data to the consumer instead
of forcing the user to do pagination to get data iteratively. Streaming
shouldn’t necessarily be on the server side; it can also be on the client side or
both sides simultaneously, which is called bi-directional streaming. In a
typical streaming use case, you open the connection once, and the data will
be streamed through this opened connection. You will see different kinds of
usages of streaming use cases, particularly in Chapter 5, while we implement
a complete application within this book.

1.2 REST vs. RPC


REST (Representational State Transfer) is a widely adopted protocol for
microservices. Still, you may start to think about using gRPC if you have
strict requirements like low latency, multi-language system support, etc...
REST is based on HTTP 1.0 Protocol that lets you exchange messages in
JSON or XML format between client and server. On the other hand, gRPC is
based RPC (Remote Procedure Call) architecture that uses Protocol Buffers
binary format to exchange data over HTTP 2.0 Protocol. This does not mean
that REST is not compatible with HTTP 2.0; you can set up your REST
services based on that protocol with your custom implementation, where it is
a built-in feature in gRPC.

Since gRPC has built-in HTTP 2.0 support, you can also use Unary and Bi-
directional streaming between clients and servers, resulting in high-speed
communication. With default settings of REST services, multiple client-
server communications can introduce a delay to your overall system
performance.

There are also cases where REST is more beneficial than gRPC. For example,
REST protocol is supported in all kinds of browsers. Since gRPC support is
minimal, you may need to use a proxy layer like gRPC Web
(https://github.com/grpc/grpc-web) to communicate easily with the gRPC
server.

gRPC has lots of advantages, like being able to define messages to exchange
data between services easily. However, regarding readability, JSON and
XML usage in REST has advantages, like changing it freely if there is no
explicit business validation for the changed fields. In contrast, you need to
follow some rules in gRPC to make a change. We will explain this in Chapter
5 in detail.

gRPC has a built-in client and server stub generation mechanism where you
need to use a framework in REST like Swagger Codegen to generate client-
side models. This becomes critical, especially once you have multiple
services and maintain multiple SDKs simultaneously for your customers.

Now that we understand the differences between REST and gRPC let's look
at when it would make sense to use gRPC."

1.3 When to Use gRPC


If you have strict requirements for browser support, then you need to think of
using REST since you will end up setting up another layer for conversion
between HTTP/2 and HTTP/1. However, you can still use gRPC for inter-
service communication and attach a gRPC load balancer
(https://aws.amazon.com/blogs/aws/new-application-load-balancer-support-
for-end-to-end-http-2-and-grpc/) to that service pool for exposing API to the
public to have REST compatibility which we will see in detail in Chapter 9.
Other alternatives include Twirp (https://github.com/twitchtv/twirp), an RPC
framework built on Protobuf. Twirp lets you enable the REST layer for gRPC
services in a way that you can access your endpoints, like in the following
example, to send a POST request with a JSON payload.
curl -X "POST" \
- H "Content-Type: application/json" \
-d '{"name": "dev-cluster"}' \ http://localhost:8080/twirp/github.c
Polyglot development environments are ideal for gRPC integrations since
using the Python client within Checkout Service to access Payment Service,
which is written using Java, is very easy with client stub generation. You can
apply the same strategy to your SDK generations for public consumers. Also,
whenever you change your service definitions, the test fails on the client side,
which is a suitable verification mechanism for your microservices. You will
learn how to test gRPC microservices in Chapter 7 in detail.

gRPC may not be the proper selection for very simple applications like
startup projects that contain only 1-2 services since maintaining the proto
files that contain service definitions is not easy, especially for inexperienced
users.

It is OK to use gRPC communication between internal services. Still,


exposing a gRPC interface to customers may not be ideal, especially if there
is no SDK for the client for gRPC service communication. If you prefer to
expose gRPC without maintaining the SDKs for your consumers, then it
would be better to share your service definitions with them or provide a clear
explanation about how to make gRPC calls to your gRPC services.

1.3.1 Who is this book for?


This book contains many explanations, code examples, tips & tricks
supported by real-life examples that can be useful for the following roles.

Developers who don’t know Go or Microservices: They can take


advantage of starting with introductory chapters about Go, Microservice,
and gRPC and learn production-grade techniques for gRPC Go
Microservices. For readers who already know Microservice
Architecture, they can refresh their knowledge with the resources
described in Go which can be easily adapted to any other language they
currently use.
Engineering Managers: They can improve team developer productivity
by adding the best practices described in their playbooks. Applying
techniques will introduce good visibility over the entire product that will
help to onboard new employees to the team quickly.
Software Architects: There are many handy examples and architectural
designs that are potential references to their decisions for new products
or features.

There will be production-grade examples in this book in the following


format.

Completed project at the end of this book


Code examples to better understand a specific topic and how it works
Automation examples, especially with GitHub Actions to reduce
repetitive operations
Preparing artifacts for deployment
Security best practices

1.4 Production-grade Use-cases


As shown in Figure 1.1, we will try to create an e-commerce product in this
book with Go gRPC microservices that is automated within a proper CI/CD
pipeline and lives in a Kubernetes environment. In the following subsections,
we’ll visit critical parts of the diagram to see how important they are for a
typical development lifecycle, how gRPC makes those parts easier to handle,
and which technologies to use where.

Figure 1.1 Architecture diagram of an e-commerce product built with Go Microservices on top of
Kubernetes, including CI/CD flow and Observability
1.4.1 Microservices
Microservice projects are full of challenges, especially at the beginning of the
project, and you will often hear the following questions in your architectural
decision meetings.

Let’s implement microservices, but how much micro should it be?


Which strategy do we need to base our construct/decompose services
on?

Dividing microservices by business capabilities is one of the options


(https://microservices.io/patterns/decomposition/decompose-by-business-
capability.html), and we will use that notation as we focus on real-life use
cases and implement them in upcoming chapters. As shown in Figure 1.1, we
have five services to provide different business features, like a Shipping
Service to ship products to the customer and a Payment Service to charge a
customer's credit card by using the information in the checkout phase
composed of cart items. There are five business capabilities: Product, Cart,
Checkout, Payment, and Shipping. They connect using their generated stubs,
e.g., Checkout uses Shipping gRPC stubs to call Shipping service functions.

Monolith to Microservice decomposition will replace service function calls


with network calls, which means you need to implement a fault-tolerant client
for inter-service communication. gRPC provides basic things like connection
pooling and resource access so that service functions can be accessed using
their gRPC stubs within the client side after adding auto-generated stubs to
consumer service as a Go dependency. As is seen in Figure 1.1, Checkout
Service can call Cart Service to get cart items, Shipping Service to get the
customer's address, and the Payment Service to charge the customer’s credit
card by adding respectively generated stubs of Shipping, Cart, and Payment
Service to Checkout Service as Go dependency. We will look at dependency
management in detail in Chapter 5; you will learn how to work with
dependencies and how to automate them to generate in CI (Continuous
Integration) Pipeline.

Microservice architecture opens a gate to the Polyglot Development


environment, which is very helpful for choosing a proper language for
different use cases. It also allows us to use various technologies like Neo4j
for Graph related use cases, MySQL if there is a need for relational table
structures or Mongo for document-based data models. Microservice
architecture also helps you to construct different small teams to assign code
ownerships to a specific pool of services

1.4.2 Container Runtime


Managing an application environment may not be a real concern if you have
a monolithic application since you can deploy this application into a set of
VMs, and a typical load balancer handles traffic. Inadequate resource
utilization, scaling problems, and risky deployments encourage people to
move to microservice architecture. However, once you switch to
microservice architecture, since each service is independent, you need to start
thinking of a distributed environment that needs proper environment
management.

Kubernetes, an open-source container orchestration platform, has already


proved itself for application deployment management and many other
production-grade use cases. The services shown in Figure 1.1 will be all
cloud-native applications and will have Kubernetes deployment specs defined
for use within CI/CD pipeline. Moreover, each service will be running within
a container and can be scaled horizontally based on the load.

gRPC needs a server address to dial in to call service functions. Kubernetes


discovery system is a good fit for finding the correct address since the server
address will be the service name of a microservice defined within a Service
spec. Suppose you have a proper naming convention for your services. In that
case, you will also have a perfect integration between the consumer and
service without any help from service discovery products to see the actual
address of a specific service.

Each service could have different behavior, like different resource requests,
different scale factors, different language runtime, and so on. Again, they are
just configurations within Kubernetes deployments that can be appropriately
configured for each service. For example, Product service needs more
capacity or scaling factor than other services since most customers search and
view products during the day. You don’t need to scale all the services
simultaneously in Kubernetes as you do for a monolithic application. It can
be handled by adding scaling factors and resource capacity to specific
services.

The main output for each service will be a cloud-native application, which
means you can deploy this service to any other container runtime like AWS
Fargate, AWS ECS, even docker for local development, and so on with a
little modification.

1.4.3 CI/CD Pipeline


There are lots of operations that are candidates for being automated within
the Microservices environment. Service artifact building, gRPC stub
generation for specific languages, testing, code quality check, and
deployment of services are some of the well-known examples. The more
automation you have for this distributed system, the less stress you have
during the development lifecycle.

You can easily use gRPC tools to generate stubs on your local environment,
but wouldn’t it be better to generate them whenever some changes are pushed
to the remote repository? Also, you can generate artifacts to deploy them to
an experimental or stable environment after merging them into the main
branch. Modern VCS providers like Github, Gitlab, and Bitbucket already
have that kind of integration, so there is not much custom implementation
needed for this level of automation.

A green check after CI/CD job execution does not mean everything is fine;
there should be a correct level of check mechanism for the services. For
example, good coverage of unit tests, proper integration tests to check 3rd
party integrations like MySQL, Kubernetes, or AWS, contract testing for
service-to-service communication, static code analysis, and vulnerability
checks are the parts for a good start to have a reliable codebase in the main
branch.

After a successful and reliable codebase, artifacts can be generated and


tagged to be deployed to the user acceptance testing (UAT) environment and
then the PROD environment for the end users. Some best practices for
deployment methodologies include Rolling Upgrade, Canary Deployment,
and Blue-Green Deployment. The main goal here is to ship the artifact,
docker image in our case, to the Kubernetes environment and be prepared to
be able to roll back once needed. The decision to roll back the operation is
not easy. Still, if you have a proper monitoring system, you can track error
rates and user feedback to decide when to roll back or introduce a hotfix to
the current version.

1.4.4 Monitoring & Observability


Monitoring is a mechanism that allows teams to watch and understand the
state of their systems. On the other hand, Observability is a mechanism that
enables teams to debug their systems. Observable systems are achieved
mainly by Metrics, Logs, and Tracing. Tracing context is critical to see any
specific request’s lifecycle, which we will also see in Chapter 9 in detail.
Let's say that a consumer uses an SDK to access an API via the API
Gateway. It propagates requests to 4-5 downstream services to handle all the
operations and returns to the customer. Having a successful response does not
mean everything is good; it is not good if there is a latency within this
lifecycle. After latency detection, request flows can be analyzed by grouping
by trace IDs that contain helpful information within their context. Trace IDs
in the requests and response headers can be injected quickly with a simple
middleware that we will see in detail in Chapter 9.

Monitoring is a crucial part of microservice architecture since once you


decompose a monolithic application into a microservice architecture, you
must introduce a solution for better visibility. Service level metrics, overall
latency, and service-to-service call hierarchy are some solutions you may
want to see in the monitoring dashboard. Besides the system-level metrics,
the logs of the services are also necessary since they allow you to track
application-level anomalies like increasing error rates.

Dashboards, panels, and graphs for your system provide a good start for
better Observability. Still, we should focus on introducing new metrics and
creating specific alarms based on them to be notified when you are away
from your dashboards. As an example, Prometheus (https://prometheus.io),
an open-source event monitoring and alerting tool, can be used to collect
system and application metrics, and there can be new alert configurations
based on those metrics like, “notify once the memory usage percentage > 80
for a specific service”. Logs are also good sources for insights since you can
calculate error rates in real-time. You can even create alert configurations
based on log patterns within modern log management tools like Elastic Stack
(Elasticsearch, Logstash, and other Elastic integration products).

With a good monitoring setup, there will not only be good insight for service-
to-service communication but there will also be insights for service-to-third-
party integrations. For example, it will be possible to detect performance
problems between service and database or service to third-party API that is
out of the organization’s control.

1.4.5 Public access


This part is a bit exceptional for your product since you need to think more
about security, which is critical for client-server communication. Security
concerns may be about accessing confidential data or resource exhaustion. If
the product does not have a proper configuration for the security layer, an
attacker can access the customers' confidential data or the underlying system.
Reputation can be destroyed not only for security reasons but also due to bad
performance. For example, if any user can send unlimited requests to your
product, this is simply a sign of bad architecture design of public access for
the product. This is because products without a throttling system can cause
resource exhaustion on the server side, negatively impacting performance.

API Gateways are widely used to prevent the above scenarios by following
certain principles, like setting up a proper authentication/authorization system
quickly, introducing rate-limiting to restrict users for their request capacity,
etc. If you are using Kubernetes already, you can handle them with built-in
features like adding authorization and rate limiting configuration to nginx
controllers; otherwise, you have other options like using API Gateway
products.

Besides a proper public access mechanism, resource naming is also crucial


since it will affect the quality of product documentation. If proper naming is
used for endpoints, it will be easier to read the documentation of API and
consume those API endpoints smoothly. Optionally, you can implement
SDKs for your product so the consumers can depend on that SDK features
instead of trying to construct requests, send them to API endpoints, and
handle responses.

We just finished a chapter with a few in-depth topics, but it sets the context
for the big picture to help you decide if Go gRPC Microservices is a good fit
for your use case. We will cover each section in detail in upcoming chapters.

1.5 Summary
gRPC performs well in inter-service communications because it uses
binary serialization for the data and transfers it through the HTTP/2
protocol.
gRPC allows you to do client streaming, server streaming, and bi-
directional streaming that allows you to send multiple requests or
receive multiple responses in parallel.
Stable Client–Server interaction in gRPC Microservices is easy because
of automatic code generation.
REST is popular primarily due to its broader browser support, but you
can still use a gRPC web proxy (e.g., https://github.com/grpc/grpc-web)
for REST-to-gRPC conversion.
Due to its high portability, Go is one of the best languages for cloud-
native applications, like microservices in kubernetes.
Using HTTP/2 over SSL/TLS end-to-end encryption connection in
gRPC eliminates most of the security concerns for a Microservice
2 gRPC Meets with Microservices
This chapter covers
Comparing advantages and disadvantages of Microservice Architecture
to Monolithic Architecture
Understanding communication patterns in Microservice Architecture
Analyzing service discovery mechanisms
Addressing the reasons behind how Go and gRPC boosts reliable inter-
service communication as well as development productivity

The fundamental goal of any software development team is to implement a


set of features to form a product to create direct or indirect business value.
The format of this product has evolved for decades, it has been distributed as
a package that you can install on your computer offline, or it has been served
as a product over the internet that you can use online. Each programming
language has its own packaging methodology; for example, you can use a
war or jar file for Java or a binary executable for Go projects. We call this
Monolithic Architecture, where one or more features/modules are packaged
as one product that does related tasks within a distributable object. Once the
scalability problems arose, alternative solutions like Microservice
Architecture became very popular, where the application is decomposed into
services based on their business capabilities. This decomposition enables us
to deploy each service independently, which we can see in detail in Chapter
8. The stability of inter-service communication is crucial to provide data
consistency among those services. This chapter will show how important
gRPC is for inter-service communication.

2.1 Monolithic Architecture


In Monolithic Architecture, the different components of a monolithic
application are combined into a single-tiered and unified software
application. It can contain UI, server, and database modules managed in one
place. Monolithic architecture is a good choice, especially while you are
developing the initial version of the product since it helps you to get familiar
with business domains without tackling any non-functional challenges.
However, it is suggested that you assess your product periodically to
understand whether it is the right time to move to Microservice Architecture.
Now that we know what monolithic architecture looks like, let us take a look
at the pros and cons of this architecture.

2.1.1 Development
All the modern IDEs are designed to support monolithic applications. For
example, you can open a multi-module maven project in IntelliJ IDEA
(https://www.jetbrains.com/idea/) or create a modular Go project with Goland
(https://www.jetbrains.com/go/) that you can easily open and navigate within
the codebase.

However, problems can arise as your codebase grows. For example, suppose
you have tens of modules within a monolithic application and try to open
them simultaneously. In that case, it is possible to overload the IDE, which
negatively impacts productivity, and it may not be relevant to open them all if
you don't need some of them.

Additionally, if you have no proper isolation on your test cases, you may run
all the tests whenever you make a small change in your codebase. The bigger
codebase, the longer compile and testing time.

2.1.2 Deployment
Deploying a monolithic application means copying a standalone package or
folder hierarchy to the server or a container runtime. However, monoliths
may be an obstacle to frequent deployments in Continuous Deployment since
it is hard to deploy and test in a reasonable time interval. You need to deploy
the entire application, even if you introduce a tiny change to a specific
component. For example, let's say that we introduced a small change in the
newsletter component responsible for serving the newsletter, and now we
want to test and deploy it to production. To have a green flag for tests, we
need to run all the tests, even though we haven't changed anything in other
components like Payment, Order, etc. In the same way, we need to build the
system to generate one artifact even though the changes are only in the
newsletter component.

On the other hand, deploying a monolithic application might have more


significant issues, especially if multiple teams share this application. Flaky
tests and broken functionalities introduced by other teams may interrupt the
entire Deployment, and you may want to revert it.

2.1.3 Scaling

Monolithic applications can be quickly and naively scaled by putting them


behind a load balancer. By doing so, client requests will be proxied to
downstream monolithic applications in physical servers or a container
runtime. However, it may not make sense from a cost perspective since those
applications are exact copies of each other, even if you don't need all the
components to be scaled in the same priority. Let's look at a simple example
to understand this utilization problem better.

Let's say that you have a monolithic application that needs 16G of memory,
and the most critical module out of 10 modules is customer service. When
you scale this monolithic application by 2, you will end up with 32G of
memory allocation. Let's say that the custom module needs 2G memory to
run efficiently. Wouldn't it be better to only scale the customer module by
two that need an extra 2G of memory instead of 16G?

Distributing monolithic application modules to different teams for fast feature


implementation is also challenging, which is another scaling problem.
Finally, once you decide to use monolithic architecture, you commit to the
technology stack long-term. Layers in monolithic applications are tightly
coupled in-process calls developed with the same technology to have
interoperability. As a developer or architect, it would be harder to try another
technology stack once they become available. We can extend this list further,
but let's look at the driving factors to scaling.

2.2 Scale Cube


Plenty of driving factors can force you to change your architecture, and
scalability is one of them for performance reasons. Scale Cube is a three-
dimension scalability model of an application. Those dimensions are X-Axis
Scaling, Y-Axis Scaling, and Z-Axis Scaling, as shown in Figure 2.1.

Figure 2.1 Scalability model of an application

2.2.1 X-Axis Scaling


This model consists of running multiple copies of the same application
behind a load balancer. In Kubernetes, load balancing is handled by Service
resources (https://kubernetes.io/docs/concepts/services-networking/service/)
which proxies request to available backend instances that live in Pod
resources (https://kubernetes.io/docs/concepts/workloads/pods/), which we
will see in Chapter 8 in detail. Those instances share the load so that if there
are N copies, every instance can handle 1/N of the load. One of the main
drawbacks of this scaling model is that since each copied instance has access
to all data, the instances will need more memory than required. Also, it does
not have an advantage for reducing the complexity of growing the codebase.

2.2.2 Z-Axis Scaling


Z-Axis Scaling is like X-Axis Scaling since the application is copied to
instances. The main difference is that each application is only responsible for
a subset of data that ends up with cost savings for resources. Since data is
partitioned across services, it also improves fault tolerance because only
some data will be inaccessible to the user.

Building a Z-Axis scaling is challenging since it introduces extra complexity


to the application. Also, you need to find a proper way of data repartition for
data recovery.

2.2.3 Y-Axis Scaling


In the Y-Axis Scaling model, scaling means splitting the application by
feature instead of having multiple copies of an application. For example, you
might decompose your application into a set of services with a couple of
related functions.

Now that we understand the pros and cons of Monolithic Architecture and
scalability models, let's take a look at how Microservices Architecture is a
form of Y-Axis Scaling

2.3 Microservice Architecture


Microservice Architecture is a form of architectural style that defines an
application as a collection of services. Those applications mainly have the
following characteristics.

They are loosely coupled


(https://en.wikipedia.org/wiki/Loose_coupling), which allows you to
create highly maintainable and testable services.
Each of the services can be deployed and scaled independently.
They are focused on business capabilities.
Each service or set of services can be easily assigned to a dedicated team
for code ownership.
No need for long-term commitment to the technology stack.
If one of the services fails, other services can continue to serve.

First, you must decide whether microservice architecture fits your product
architecture well. As we already addressed, starting with monolithic
architecture is a best practice that allows you to understand your business
capabilities. Once you start having scalability problems, less productive
development, or longer release lifecycles, you can assess your environment to
see whether functional decomposition is a good fit for your application. Once
you decide to use microservice architecture, you might have independently
scalable services, small projects that contain only specific context during
development, and faster deployments due to faster test verification and small
release artifacts.

Let's assume you are familiar with your business model and know how to
decompose your application into small services. You will have other
challenges not visible in monolithic applications, such as handling data
consistency and inter-service communication.

2.3.1 Handling Data Consistency


Having consistent data is an essential goal for almost any kind of application.
In Monolithic Architecture, data consistency is generally ensured by
transactions. A transaction is a series of actions that all should be completed
successfully. All the operations are automatically rolled back if even one
action fails. To have consistent data, the transaction begins first, actual
business logic is executed, and the transaction is committed for a successful
case or rolled back in case of failure. As an example, let's assume once
Order:create() method is executed, it calls a series of actions like
Payment:create() and Shipping:start(). If both Payment and Shipping
operations succeed, it will successfully commit Order status as SUCCESS.
Likewise, if the Shipping operation fails, it rolls back Payment operation and
marks Order operation as FAILED.

Figure 2.2 Consistency of the Order data is managed by transaction boundaries which are
committed and rollback
A typical transaction can be expressed with the steps begin and
commit/rollback, where you begin a transaction and execute the actual
operation; then, it may end up committing data into the data store or roll back
the entire operation made in the transaction. Now that we understand data
consistency can be easily handled in Monolithic Architecture let's look at
how it is handled in Microservice Architecture.

2.3.2 Saga Pattern

Transactions are the critical part of an application responsible for maintaining


data consistency. In a monolithic application, there is a single data source in
the same application, but once you switch to microservices architecture, the
data state is spread across services. Each of the services has its own data
store, which means a single transaction cannot handle the consistency of the
data. To have data consistency in a distributed system, you probably have
two famous options: Two-phase commit (https://en.wikipedia.org/wiki/Two-
phase_commit_protocol) and Saga. 2PC (two-phase commit) coordinates all
the processes which form distributed atomic transactions on whether they
should be committed or aborted. A Saga is a sequence of local transactions
that updates each service and publishes another message to trigger another
local transaction on the next service.

As you can see, since transaction steps are spanned across the services, it is
not something that you can handle with an annotation or two lines of code.
However, there are widely used practices with Saga, so you don't need to
reinvent the wheel from scratch for your use cases. Choreography and
Orchestrator-based Saga are the most popular patterns widely used for inter-
service communication to have consistent data.

2.3.3 Choreography-based Saga

Choreography-based Saga is a pattern where each service executes its local


transaction and publishes an event to trigger the next service to execute its
local transaction. Whenever a Saga is created, it can be completed in the
following patterns.

Service returns the result to the client once Saga is completed. It


receives an event to update its domain object's status as Succeeded or
Failed.
Saga is created, and the client starts to poll the next service to get either
Succeeded or Failed response. The unique identifier to start polling
should be returned directly when Saga is created.
Saga is created, and the client uses a WebSocket connection where the
service sends the result back using WebSocket protocol. Saga will be
completed once the Succeeded or Failed result is returned.

Now let's look at how to apply one of the above notations to a real-life use-
case for order creation flow.

In a typical order creation flow, Saga is created in Order Service, and Order
is created with PENDING state. It sends an event called order_created right
after Order is persisted and consumed by Payment Service. Payment Service
will try to charge the customer and send another event, payment_created or
payment_failed. If it fails, Order Service will be notified, and Order will be
marked as FAILED. Shipping Service will consume the event and initiate the
shipping process if it is successful. Finally, it will create another event for
failure or success which will cause Order status to be marked as FAILED or
SUCCESS.

Figure 2.3 Choreography of service interactions by using event channels

Service communications over queue can be handled in 2 ways.

Command Channels where the publisher sends a message directly to


the next service with replyToChannel parameter so that it can notify the
consumer once it completes the operation and commits the transaction.
The main drawback of this pattern is that the publisher needs to know
the location of the next service.
Pub/Sub Mechanism is where the publisher publishes a domain event,
and the interested consumers can consume messages to process and
Random documents with unrelated
content Scribd suggests to you:
and happiness which the kingdom of Poland had enjoyed to a
degree till then unknown, vanished in the midst of civil war and a
general devastation. All these evils are now passed. The kingdom of
Poland, again subject to our sceptre, will regain tranquillity, and
again flourish in the bosom of peace, restored to it under the
auspices of a vigilant government. Hence we consider it one of our
most sacred duties to watch with paternal care over the welfare of
our faithful subjects, and to use every means in our power to
prevent the recurrence of similar catastrophes, by taking from the ill-
disposed the power of disturbing public tranquillity. As it is,
moreover, our wish to secure to the inhabitants of Poland the
continuance of all the essential requisites for the happiness of
individuals, and of the country in general, namely, security of
persons and property, liberty of conscience, and all the laws and
privileges of towns and communes, so that the kingdom of Poland,
with a separate administration adapted to its wants, may not cease
to form an integral part of our empire, and that the inhabitants of
this country may henceforward constitute a nation united with the
Russians by sympathy and fraternal sentiments, we have, according
to these principles, ordained and resolved this day, by a new organic
statute, to introduce a new form and order in the administration of
our kingdom of Poland.
'St Petersburgh, February 26, 1832.

'NICHOLAS.

'The Secretary of State, Count Stephen Grabowski.'


After this Manifesto, the organic statutes of Poland are given, the
principal of which are as follows:

'By the grace of God, we, Nicholas I, Emperor and Autocrat of all the
Russias, King of Poland, &c., &c.
'In our constant solicitude for the happiness of the nations which
Providence has confided to our government, we are occupied in
fixing the basis for the future organization of the kingdom of Poland,
having regard to the true interests and positions of the country, and
to the local wants and manners of the inhabitants.
'GENERAL DISPOSITIONS.
'Art. 1. The kingdom of Poland is forever to be re-united to the
Russian empire, and form an inseparable part of that empire. It shall
have a particular administration conformably to its local necessities,
as well as a civil and military code. The statutes and the laws of
cities and towns remain in full vigor.
'Art. 2. The Crown of the kingdom of Poland is hereditary in our
person and in our heirs and successors, agreeably to the order of
succession to the throne prescribed by all the Russias.
'Art. 3. The Coronation of the Emperors of all the Russias and Kings
of Poland shall be one and the same ceremonial, which shall take
place at Moscow, in the presence of a deputation from the kingdom
of Poland, which shall assist at that solemnity with the deputies from
the other parts of the empire.
'Art. 4. In the possible event of a regency in Russia, the power of the
regent or regentess of the empire will extend over the kingdom of
Poland.
'Art. 5. The freedom of worship is guarantied; every one is at liberty
to exercise his religion openly, under the protection of Government;
and the difference of Christian faiths shall never prove a pretext for
the violation of the rights and privileges which are allowed to all the
inhabitants. The Roman Catholic religion, being that of the majority
of our Polish subjects, shall be the object of especial protection of
the Government.
'Art. 6. The funds which the Roman Catholic clergy possess, and
those of the Greek church united, shall be considered as the
common and inviolable property of the hierarchy of each of those
creeds.
'Art. 7. The protection of the laws is assured to all the inhabitants
without distinction of rank or class. Each shall be empowered to
assume dignities or to exercise public functions, according to his
personal merits or talents.
'Art. 8. Individual liberty is guarantied and protected by the existing
laws. No one shall be deprived of his liberty, or called to justice, if he
be not a transgressor of the law in all the forms prescribed. Every
one detained shall be apprised of the motive of arrest.
'Art. 9. Each person arrested must submit to a delay of three days to
be heard and judged of, according to the forms of law, before
competent tribunals: if he be found innocent, he will instantly obtain
his liberty. He will be equally restored to liberty who shall furnish a
sufficient surety.
'Art. 10. The form of judicial inquests directed against the superior
functionaries of the kingdom, and against persons accused of high
treason, shall be determined by a particular law, the foundation of
which shall be accordant with the other laws of our empire.
'Art. 11. The right of property of individuals, and of corporations, is
declared sacred and inviolable, inasmuch as it will be conformable to
the existing laws. All the subjects of the kingdom of Poland are
perfectly free to quit the country, and to carry away their goods,
provided they conform to the regulations published to that effect.
'Art. 12. The penalty of confiscation shall not be enforced but against
state crimes of the first class, as may be hereafter determined by
particular laws.
'Art. 13. Publication of sentiments, by means of the press, shall be
subjected to restrictions which will protect religion, the inviolability of
superior authority, the interests of morals, and personal
considerations. Particular regulations, to this effect, will be published
according to the principles which serve as a basis to this object in
the other parts of our empire.
'Art. 14. The kingdom of Poland shall proportionably contribute to
the general expenditure and to the wants of the empire. The
proportion of taxes will be stated hereafter.
'Art. 15. All contributions and all taxes which existed in November,
1830, shall be levied after the manner formerly settled till the new
fixing of taxes.
'Art. 16. The treasury of the kingdom of Poland, and all the other
branches of the administration, shall be separated from the
administration of the other parts of the kingdom.
'Art. 17. The public debt of Poland, acknowledged by us, shall be
guarantied as formerly, by the government, and indemnified by the
receipts of the kingdom.
'Art. 18. The bank of the kingdom of Poland, and the laws respecting
credit, shall continue under the protection of Government.
'Art. 19. The mode of commercial transactions between the Russian
empire and the kingdom of Poland shall be regulated according to
the respective interests of the two countries.
'Art. 20. Our army in the empire and in the kingdom shall compose
one in common, without distinction of Russian or Polish troops. We
shall reserve to ourselves a future decision of this, by an especial
law, by what arrangement, and upon what basis, the kingdom of
Poland shall participate with our army. The number of troops which
shall serve as the military defence of the kingdom will be also
ultimately determined upon by a law.
'Art. 21. Those of our subjects of the empire of Russia, who are
established in the kingdom of Poland, who possess or shall possess,
real property in that country, shall enjoy all the rights of natives. It
shall be the same with those of our subjects of the kingdom of
Poland, who shall establish themselves, and shall possess property,
in the other provinces of the empire. We reserve to ourselves to
grant hereafter letters of naturalization to other persons, as well to
strangers as to Russians, who are not yet established there. Those
of our subjects of the Russian empire who may reside for a certain
time in Poland, and those of our subjects of the kingdom of Poland
who may sojourn in the other parts of the empire, are subject to the
laws of the country where they reside.
'Art. 22. The superior administration of the kingdom of Poland is
confided to a council of administration, which shall govern the
kingdom in our name, under the presidency of the governor of the
kingdom.
'Art. 23. The council of administration is composed of the governor
of the kingdom, of superior directors, who superintend the
commissions, and among whom are divided the interests of the
administration, of comptroller, presiding over the supreme Chamber
of Finance, and of other members, whom we shall appoint by special
orders.'
FOOTNOTES:
[85] Not having a copy of this address in the original, we make
use of a rather unsatisfactory translation, which we find in the
journals of the day.

LIST OF POLISH NAMES,


With their Pronunciation in English.
POLISH ALPHABET.
a b c d e f g h i j k l m n o p q

ah bey tsey dey ey ef ghey hah ye ee kah el em en o pey koo

r s t u w x y z.

err es tey oo voo ix ee zed.


Note. In every Polish name, or word, the letters are all sounded and
pronounced, as their names indicate.
Names as spelled in Their pronunciation. Polish.
A
Adamski Ahdamsky
Augustow Owgoostov
Alexota Ahlexotah
B
Bestuzew Bestoozhev
Boleslaw-Chrobry Boleslav-Khrobry
Biala-Cerkiew Beahlah-Tseyrkyev
Bilinski Belinsky
Biernacki Byernatsky
Bialystok Beahlistok
Brzesc Brzhests
Boimie Boimea
Boguslawski Bogooslavsky
Bialolenka Beahlolenkah
Bug Boog
Bielak Bieylak
Berowski Beyrovsky
Blendowsky Blendovsky
Bystrzyca Bistrzhitsa
Berzykowski Berzhyhkovsky
Beysogola Beysogolah
Bialowiez Beahlovyezh
Belzyca Belzheetsah
Borowa Borovah
Beresteczko Beyrestechko
Bady Bahdy
Brainsk Brainsk
Bielsk Byelsk
Bukowski Bookovsky
Bialobrzegi Byahlobrzheygy
Bocki Botsky
Blonie Blony
C
Chlopicki Khlopitsky
Chodkiewicz Khodkyavitch
Czarnecki Tcharnetsky
Czartoryski Tchartorisky
Ciechanowiec Tsyakhanovyets
Czyzewski Tcheejevski
Czaykowski Tshahovski
Czarno-morskie Tcharna-morskyey
Chlapowski Khlaposvky
Ceglow Tseyglov
Chrzanowski Khrzhahnovsky
Czyzew Tcheejev
Czaykiszki Tchaikishki
Czenstochowa Tchenstokhovah
Cytowiany Tsetoviahny
Czarna Tcharnah
Ciechanow Tsyeykhhanov
Chodzko Khodzko
D
Dembek Dembek
Downarowicz Dovnarovich
Dombrowski Dombrovsky
Diebitsch Deebich
Dwernicki Dvernitsky
Dobre Dobrey
Dembe-Wielkie Dembey-Vielkye
Dnieper Dneeper
Dembinski Dembinsky
Dawgeliszki Davgalishky
Dubno Doobno
Dlugie-Siodlo Dloogya-Syodlo
Dobzyn Dobzhin.
G
Grabowski Grahbovsky
Grodno Grodno
Grochow Grokhov
Granica Grahnitsah
Goclaw Gotslav
Gotembiewski Gotembyevsky
Gielgud Gyelgood
Grombkow Grombkov
Gruszki Grooshky
Galiczyn Gahlichyn
Graiewo Grahyeyvo
Gielgudyszki Gyelgoodishky
Gury-Konarskie Goory-Konarskya
Gorzdy Gorsdy
Giedroyc Gyedroits
H
Hauke Houka
Hildebrand Hildeybrand
Hurtig Hoortig
J
Jablonowski Yablonovsky
Jgelstrom Eegelstrom
Jurgaszko Yoorgashko
Jezierski Yazhyersky
Jadow Yahdov
Jablonna Yablonnah
Jakubow Yahkoobov
Januwek Yahnoovek
Jankowski Yankovsky
Jendrzeiow Yendrzhagov
Jarburg Yarboorg
Jagiellow Yahgyellov
Jedlina Yedlenah
Janow Yahnov
Jeroma Yaroma
K
Kosciuszko Kostchioushko
Krzyzanowski Krzhezhanovsky
Kichelbeker Keekhelbaker
Kachowski Kakhovsky
Krasinski Krahsinsky
Kornatowski Kornahtovsky
Kozienice Kozhyanetsey
Krukowiecki Krookovyetsky
Kock Kotsk
Kaluszyn Kahlooshyn
Kostrzyn Kostrzhyn
Konik Konyik
Kawenczyn Kahvenchyn
Kicki Keetsky
Krasny-taw Krasneestav
Kozieradzki Kozhyaradzky
Karczew Karchev
Kurow Koorov
Konskawola Konskahvolah
Keydany Kaydahny
Kowno Kovno
Kazimierz Kahzheemyerzh
Kolodno Kolodno
Krzemieniece Krzheymyeynyets
Knielce Knyeltsa
Kuflew Kooflev
Kolacze Kolachey
Kamionka Kahmyonkah
Kleczkowo Klechkovo
Kaminski Kaminsky
Koss Koss
Kalwaryia Kalvahreya
Karwowska Kavovskah
Kurzany Koorzhahny
Kikiernicki Kekyornitsky
Kniaziewicz Knyahzyavich
L
Lubowidzki Looboveedzky
Lazienki Lahzhyenky
Lelewel Leyleyvel
Lubecki Loobetsky
Lubinski Loobinsky
Lowicz Lovich
Lubomirska Loobomeerskah
Lenczna Lenchnah
Lukow Lookov
Lublin Looblin
Liwiec Levyets
Leduchowski Leydookhovsky
Lagowski Lahgovsky
Lewandowski Leyvandovsky
Latowicz Lahtovich
Lipawa Lepahvah
Lukowiec Lookovyets
Lomza Lomzah
Lubartow Loobartov
Lubania Loobahnyah
Lipinska Lepinskah
Lida Ledah
Lysobyki Lysobyky
Laskarzew Laskarzhev
Laga Lahgah
Luberacz Loobeyrach
M
Murawiew Mooravyev
Mieciszewski Myatsishevsky
Mokotow Mokotov
Miendzyrzyc Myenjeerzhyts
Makowiec Mahkovyets
Minsk Minsk
Macieiowice Matsyaovcetsa
Mingosy Mingosy
Milosna Melosna
Makow Mahkov
Malachowski Mahlahkhovsky
Maslowski Maslovsky
Markuszew Markushev
Magnuszewo Magnooshavo
Memel Mamel
Mycielski Meetsyelsky
Modlin Modlin
Milatyn Meelahtyn
Mordy Mordy
Modzele Modzala
Mniszew Mneshev
Menzynin Menzhenin
Malinowski Mahlenovsky
Mlawa Mlahvah
Matusiewicz Mahtoosyavich
Myszogola Meshogolah
Michalowski Mekhahlovsky
Maluszyn Mahlooshyn
Morawski Moravsky
N
Niemcewicz Nyemtseyvich
Nasielsk Nahsyelsk
Narew Nahrev
Nowawies Novah-vies
Nowy-dwor Novy-dvor
Niewiaza Nyavyahzhah
Narewska Nahrevkah
Nurzec Noorzhets
Neydenburg Nidenboorg
Nowe-miasto Nova-myasto
Nadarzyn Nahdarzhyn
O
Ostrowski Ostrovsky
Ostrolenka Ostrolenkah
Orsyca Orseetsah
Okuniew Okoonyev
Osmiany Osmyahny
Ostrog Ostrog
Orla Orlah
Oyrany Oyrahny
P
Plichta Plikhtah
Pestel Pestel
Potocki Pototsky
Poniatowski Ponyahtovsky
Powonzki Povonsky
Pac Pats
Pultusk Pooltoosk
Parczewo Parchavo
Praga Prahgah
Pientka Pyentkah
Paszkiewicz Pashkyavich
Pulawy Poolahoy
Polonga Polongah
Prondzynski Proodzynsky
Piast Pyast
Plomieniec Plomyanyets
Proskirow Proskerov
Piaski Pyasky
Poznan Pornan
Prasynsz Prasnysh
Plater Plahter
Podbrzeze Podbrzhazha
Piwecki Pevetsky
Pawenduny Pahvendoony
Piaseczno Pyasechno
R
Rozniecki Rozhnyetsky
Releiew Reyleyiev
Rukiewicz Rookyavich
Ruda Roodah
Ryczywol Reecheevol
Radom Rahdom
Radomierza Rahdomyerzhah
Radzimin Rahjeemin
Rybinski Reebinsky
Rozany Rozhahny
Rosseyny Rosseyny
Radziwil Rahjecvel
Radziwilow Rahjeevelov
Raygrod Raigrod
Rumszyski Roomshysky
Rewdany Revdahny
Rasinowicz Rahsenovich
Retow Retov
Racioncz Rahtsyonzh
Ruzycki Roozhytsky
S
Sokolnicki Sokolnitsky
Soltyk Soltyk
Szlegel Shleygel
Suwarow Soovahrov
Sobieski Sobyesky
Sapieha Sahpyahah
Szulec Shoolets
Siemiontkowski Syamyontkovsky
Skrzynecki Skrzhynetsky
Szembek Shembek
Sierawski Syeyravsky
Siedlce Syedltsa
Serock Seyrotsk
Stryinski Stryinsky
Seroczyn Serochyn
Sokolow Sokolov
Stoczek Stochek
Swider Sveder
Stanislawow Stahneslahvov
Swierza Svyerzhah
Szachowski Shakhovsky
Skarzynski Skarkhynsky
Siekierki Syakerky
Sznayder Shnider
Szuszerin Shoosherin
Siennica Syenneetsah
Szymanski Shymansky
Szawla Shavlah
Swienciany Svyentsyahny
Szerwinty Shervinty
Sucha Sookhah
Styr Styr
Stary- Stahry-
Konstantynow Konstantenov
Starygrod Stahregrod
Stoiadly Stoyadly
Strzebucza Strzhaboocha
Suraz Sooraz
Sierakowski Syeyrahkovsky
Szymanowski Shemahnovsky
Szczuczyn Shchoochyn
Suwalki Soovalky
Swieta Svieytah
Salacki Sahlatsky
Slupecki Sloopeytsky
Sloboda Slobodah
Sonk Sonk
Siemiatycze Syamyahtecha
T
Tarnowski Tarnovsky
Trembicki Trembitski
Turno Toorno
Targowek Targovek
Troki Troky
Tarnopol Tarnopol
Tarnogura Tarnogoorah
Troszyn Troshyn
Tykocin Tykotsin
U
Uminski Oominski
Uscilug Oostseloog
Uchania Ookhanyah
W
Wigielin Vegyalen
Wielkaniee Vyelkahneetsa
Wiliaminow Velyahmeenov
Wyzechowski Vezhakhovsky
Wysocki Vesotsky
Wengrzecki Vengrzhetsky
Wonsowicz Vonsovich
Wolicki Volitsky
Wlodawa Vlodahvah
Wielezynski Vealazhynsky
Wengrow Vengrov
Wawr Vavr
Wkra Vkrah
Wilanow Velahnov
Wodynie Vodenya
Wieprz Vyeyprzh
Wilno Vilno
Wilkomierz Vilkomyerzh
Wereszczaki Vareshchahky
Wielkie Vyelkya
Wyszkow Vyshkov
Wroclaw Vrotslav
Wiliia Veleyah
Worna Vornah
Wierzbna Vyerzhbnah
Z
Zamoyski Zahmoisky
Zymirski Zymeersky
Zegrz Zeygrzh
Zlotoria Zlotoryah
Zelechow Zheyleykhov
Ziemiecki Zyeymyeytsky
Zombky Zombky
Zagroby Zahgroby
Zaluski Zahloosky
Zoliborz Zoleborzh
Zimna-woda Zimna-vodah
Zamosc Zahmosts
Zambrowo Zambrovo
Zeymy Zaymy
Zawadzka Zahvadzkah
Zaliwski Zahlivsky
Zabiello Zabyello

[Transcribers Note: Original


spelling of names and place-
names has been retained]
*** END OF THE PROJECT GUTENBERG EBOOK HISTORY OF THE
LATE POLISH REVOLUTION AND THE EVENTS OF THE CAMPAIGN
***

Updated editions will replace the previous one—the old editions


will be renamed.

Creating the works from print editions not protected by U.S.


copyright law means that no one owns a United States
copyright in these works, so the Foundation (and you!) can copy
and distribute it in the United States without permission and
without paying copyright royalties. Special rules, set forth in the
General Terms of Use part of this license, apply to copying and
distributing Project Gutenberg™ electronic works to protect the
PROJECT GUTENBERG™ concept and trademark. Project
Gutenberg is a registered trademark, and may not be used if
you charge for an eBook, except by following the terms of the
trademark license, including paying royalties for use of the
Project Gutenberg trademark. If you do not charge anything for
copies of this eBook, complying with the trademark license is
very easy. You may use this eBook for nearly any purpose such
as creation of derivative works, reports, performances and
research. Project Gutenberg eBooks may be modified and
printed and given away—you may do practically ANYTHING in
the United States with eBooks not protected by U.S. copyright
law. Redistribution is subject to the trademark license, especially
commercial redistribution.

START: FULL LICENSE


THE FULL PROJECT GUTENBERG LICENSE
PLEASE READ THIS BEFORE YOU DISTRIBUTE OR USE THIS WORK

To protect the Project Gutenberg™ mission of promoting the


free distribution of electronic works, by using or distributing this
work (or any other work associated in any way with the phrase
“Project Gutenberg”), you agree to comply with all the terms of
the Full Project Gutenberg™ License available with this file or
online at www.gutenberg.org/license.

Section 1. General Terms of Use and


Redistributing Project Gutenberg™
electronic works
1.A. By reading or using any part of this Project Gutenberg™
electronic work, you indicate that you have read, understand,
agree to and accept all the terms of this license and intellectual
property (trademark/copyright) agreement. If you do not agree
to abide by all the terms of this agreement, you must cease
using and return or destroy all copies of Project Gutenberg™
electronic works in your possession. If you paid a fee for
obtaining a copy of or access to a Project Gutenberg™
electronic work and you do not agree to be bound by the terms
of this agreement, you may obtain a refund from the person or
entity to whom you paid the fee as set forth in paragraph 1.E.8.

1.B. “Project Gutenberg” is a registered trademark. It may only


be used on or associated in any way with an electronic work by
people who agree to be bound by the terms of this agreement.
There are a few things that you can do with most Project
Gutenberg™ electronic works even without complying with the
full terms of this agreement. See paragraph 1.C below. There
are a lot of things you can do with Project Gutenberg™
electronic works if you follow the terms of this agreement and
help preserve free future access to Project Gutenberg™
electronic works. See paragraph 1.E below.
1.C. The Project Gutenberg Literary Archive Foundation (“the
Foundation” or PGLAF), owns a compilation copyright in the
collection of Project Gutenberg™ electronic works. Nearly all the
individual works in the collection are in the public domain in the
United States. If an individual work is unprotected by copyright
law in the United States and you are located in the United
States, we do not claim a right to prevent you from copying,
distributing, performing, displaying or creating derivative works
based on the work as long as all references to Project
Gutenberg are removed. Of course, we hope that you will
support the Project Gutenberg™ mission of promoting free
access to electronic works by freely sharing Project Gutenberg™
works in compliance with the terms of this agreement for
keeping the Project Gutenberg™ name associated with the
work. You can easily comply with the terms of this agreement
by keeping this work in the same format with its attached full
Project Gutenberg™ License when you share it without charge
with others.

1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside
the United States, check the laws of your country in addition to
the terms of this agreement before downloading, copying,
displaying, performing, distributing or creating derivative works
based on this work or any other Project Gutenberg™ work. The
Foundation makes no representations concerning the copyright
status of any work in any country other than the United States.

1.E. Unless you have removed all references to Project


Gutenberg:

1.E.1. The following sentence, with active links to, or other


immediate access to, the full Project Gutenberg™ License must
appear prominently whenever any copy of a Project
Gutenberg™ work (any work on which the phrase “Project
Gutenberg” appears, or with which the phrase “Project
Gutenberg” is associated) is accessed, displayed, performed,
viewed, copied or distributed:

This eBook is for the use of anyone anywhere in the United


States and most other parts of the world at no cost and
with almost no restrictions whatsoever. You may copy it,
give it away or re-use it under the terms of the Project
Gutenberg License included with this eBook or online at
www.gutenberg.org. If you are not located in the United
States, you will have to check the laws of the country
where you are located before using this eBook.

1.E.2. If an individual Project Gutenberg™ electronic work is


derived from texts not protected by U.S. copyright law (does not
contain a notice indicating that it is posted with permission of
the copyright holder), the work can be copied and distributed to
anyone in the United States without paying any fees or charges.
If you are redistributing or providing access to a work with the
phrase “Project Gutenberg” associated with or appearing on the
work, you must comply either with the requirements of
paragraphs 1.E.1 through 1.E.7 or obtain permission for the use
of the work and the Project Gutenberg™ trademark as set forth
in paragraphs 1.E.8 or 1.E.9.

1.E.3. If an individual Project Gutenberg™ electronic work is


posted with the permission of the copyright holder, your use and
distribution must comply with both paragraphs 1.E.1 through
1.E.7 and any additional terms imposed by the copyright holder.
Additional terms will be linked to the Project Gutenberg™
License for all works posted with the permission of the copyright
holder found at the beginning of this work.

1.E.4. Do not unlink or detach or remove the full Project


Gutenberg™ License terms from this work, or any files
containing a part of this work or any other work associated with
Project Gutenberg™.

1.E.5. Do not copy, display, perform, distribute or redistribute


this electronic work, or any part of this electronic work, without
prominently displaying the sentence set forth in paragraph 1.E.1
with active links or immediate access to the full terms of the
Project Gutenberg™ License.

1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if
you provide access to or distribute copies of a Project
Gutenberg™ work in a format other than “Plain Vanilla ASCII” or
other format used in the official version posted on the official
Project Gutenberg™ website (www.gutenberg.org), you must,
at no additional cost, fee or expense to the user, provide a copy,
a means of exporting a copy, or a means of obtaining a copy
upon request, of the work in its original “Plain Vanilla ASCII” or
other form. Any alternate format must include the full Project
Gutenberg™ License as specified in paragraph 1.E.1.

1.E.7. Do not charge a fee for access to, viewing, displaying,


performing, copying or distributing any Project Gutenberg™
works unless you comply with paragraph 1.E.8 or 1.E.9.

1.E.8. You may charge a reasonable fee for copies of or


providing access to or distributing Project Gutenberg™
electronic works provided that:

• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”

• You provide a full refund of any money paid by a user who


notifies you in writing (or by e-mail) within 30 days of receipt
that s/he does not agree to the terms of the full Project
Gutenberg™ License. You must require such a user to return or
destroy all copies of the works possessed in a physical medium
and discontinue all use of and all access to other copies of
Project Gutenberg™ works.

• You provide, in accordance with paragraph 1.F.3, a full refund of


any money paid for a work or a replacement copy, if a defect in
the electronic work is discovered and reported to you within 90
days of receipt of the work.

• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.

1.E.9. If you wish to charge a fee or distribute a Project


Gutenberg™ electronic work or group of works on different
terms than are set forth in this agreement, you must obtain
permission in writing from the Project Gutenberg Literary
Archive Foundation, the manager of the Project Gutenberg™
trademark. Contact the Foundation as set forth in Section 3
below.

1.F.

1.F.1. Project Gutenberg volunteers and employees expend


considerable effort to identify, do copyright research on,
transcribe and proofread works not protected by U.S. copyright
law in creating the Project Gutenberg™ collection. Despite these
efforts, Project Gutenberg™ electronic works, and the medium
on which they may be stored, may contain “Defects,” such as,
but not limited to, incomplete, inaccurate or corrupt data,
transcription errors, a copyright or other intellectual property
infringement, a defective or damaged disk or other medium, a
computer virus, or computer codes that damage or cannot be
read by your equipment.

1.F.2. LIMITED WARRANTY, DISCLAIMER OF DAMAGES - Except


for the “Right of Replacement or Refund” described in
paragraph 1.F.3, the Project Gutenberg Literary Archive
Foundation, the owner of the Project Gutenberg™ trademark,
and any other party distributing a Project Gutenberg™ electronic
work under this agreement, disclaim all liability to you for
damages, costs and expenses, including legal fees. YOU AGREE
THAT YOU HAVE NO REMEDIES FOR NEGLIGENCE, STRICT
LIABILITY, BREACH OF WARRANTY OR BREACH OF CONTRACT
EXCEPT THOSE PROVIDED IN PARAGRAPH 1.F.3. YOU AGREE
THAT THE FOUNDATION, THE TRADEMARK OWNER, AND ANY
DISTRIBUTOR UNDER THIS AGREEMENT WILL NOT BE LIABLE
TO YOU FOR ACTUAL, DIRECT, INDIRECT, CONSEQUENTIAL,
PUNITIVE OR INCIDENTAL DAMAGES EVEN IF YOU GIVE
NOTICE OF THE POSSIBILITY OF SUCH DAMAGE.

1.F.3. LIMITED RIGHT OF REPLACEMENT OR REFUND - If you


discover a defect in this electronic work within 90 days of
receiving it, you can receive a refund of the money (if any) you
paid for it by sending a written explanation to the person you
received the work from. If you received the work on a physical
medium, you must return the medium with your written
explanation. The person or entity that provided you with the
defective work may elect to provide a replacement copy in lieu
of a refund. If you received the work electronically, the person
or entity providing it to you may choose to give you a second
opportunity to receive the work electronically in lieu of a refund.
If the second copy is also defective, you may demand a refund
in writing without further opportunities to fix the problem.

1.F.4. Except for the limited right of replacement or refund set


forth in paragraph 1.F.3, this work is provided to you ‘AS-IS’,
WITH NO OTHER WARRANTIES OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR ANY PURPOSE.

1.F.5. Some states do not allow disclaimers of certain implied


warranties or the exclusion or limitation of certain types of
damages. If any disclaimer or limitation set forth in this
agreement violates the law of the state applicable to this
agreement, the agreement shall be interpreted to make the
maximum disclaimer or limitation permitted by the applicable
state law. The invalidity or unenforceability of any provision of
this agreement shall not void the remaining provisions.

1.F.6. INDEMNITY - You agree to indemnify and hold the


Foundation, the trademark owner, any agent or employee of the
Foundation, anyone providing copies of Project Gutenberg™
electronic works in accordance with this agreement, and any
volunteers associated with the production, promotion and
distribution of Project Gutenberg™ electronic works, harmless
from all liability, costs and expenses, including legal fees, that
arise directly or indirectly from any of the following which you
do or cause to occur: (a) distribution of this or any Project
Gutenberg™ work, (b) alteration, modification, or additions or
deletions to any Project Gutenberg™ work, and (c) any Defect
you cause.

Section 2. Information about the Mission


of Project Gutenberg™
Project Gutenberg™ is synonymous with the free distribution of
electronic works in formats readable by the widest variety of
computers including obsolete, old, middle-aged and new
computers. It exists because of the efforts of hundreds of
volunteers and donations from people in all walks of life.

Volunteers and financial support to provide volunteers with the


assistance they need are critical to reaching Project
Gutenberg™’s goals and ensuring that the Project Gutenberg™
collection will remain freely available for generations to come. In
2001, the Project Gutenberg Literary Archive Foundation was
created to provide a secure and permanent future for Project
Gutenberg™ and future generations. To learn more about the
Project Gutenberg Literary Archive Foundation and how your
efforts and donations can help, see Sections 3 and 4 and the
Foundation information page at www.gutenberg.org.

Section 3. Information about the Project


Gutenberg Literary Archive Foundation
The Project Gutenberg Literary Archive Foundation is a non-
profit 501(c)(3) educational corporation organized under the
laws of the state of Mississippi and granted tax exempt status
by the Internal Revenue Service. The Foundation’s EIN or
federal tax identification number is 64-6221541. Contributions
to the Project Gutenberg Literary Archive Foundation are tax
deductible to the full extent permitted by U.S. federal laws and
your state’s laws.

The Foundation’s business office is located at 809 North 1500


West, Salt Lake City, UT 84116, (801) 596-1887. Email contact
links and up to date contact information can be found at the
Foundation’s website and official page at
www.gutenberg.org/contact
Section 4. Information about Donations to
the Project Gutenberg Literary Archive
Foundation
Project Gutenberg™ depends upon and cannot survive without
widespread public support and donations to carry out its mission
of increasing the number of public domain and licensed works
that can be freely distributed in machine-readable form
accessible by the widest array of equipment including outdated
equipment. Many small donations ($1 to $5,000) are particularly
important to maintaining tax exempt status with the IRS.

The Foundation is committed to complying with the laws


regulating charities and charitable donations in all 50 states of
the United States. Compliance requirements are not uniform
and it takes a considerable effort, much paperwork and many
fees to meet and keep up with these requirements. We do not
solicit donations in locations where we have not received written
confirmation of compliance. To SEND DONATIONS or determine
the status of compliance for any particular state visit
www.gutenberg.org/donate.

While we cannot and do not solicit contributions from states


where we have not met the solicitation requirements, we know
of no prohibition against accepting unsolicited donations from
donors in such states who approach us with offers to donate.

International donations are gratefully accepted, but we cannot


make any statements concerning tax treatment of donations
received from outside the United States. U.S. laws alone swamp
our small staff.

Please check the Project Gutenberg web pages for current


donation methods and addresses. Donations are accepted in a
number of other ways including checks, online payments and

You might also like