Monday, April 26, 2021

Nginx Reverse Proxy

Today we'll learn how to configure Nginx as a reverse proxy. First we need to download Nginx from its website. At the moment of this writing we use nginx version 1.19.10. After downloading and extracting it to a folder, we can click nginx.exe. Then verify that it is running by opening browser and type http://localhost/




This page contains commands to start, stop nginx.


Next we need to configure reserve proxy. Open nginx.conf in C:\nginx-1.19.10\conf folder.


In the http->server->location add proxy_pass. Here we add proxy_pass http://localhost:9899/; as we want to hide our gateway-server app behind reverse proxy.


Now in the browser we can use http://localhost/greeting/morning instead of our gateway-server app http://localhost:9899/greeting/morning.



Monday, April 19, 2021

Spring Boot - Prometheus - Grafana

In this post we will learn how to monitor our gateway-server using Prometheus and Grafana. First we need to add dependency to micrometer-registry-prometheus in our maven pom.xml file as shown below.



Next we need to expose actuator prometheus in our application.properties file as shown below.



We have finished making additional config in our gateway-server project. Now we can open browser and check if actuator prometheus is available using gateway-server actuator url http://localhost:9899/actuator/prometheus.



Now we need to download and run prometheus from its website here. Extract it and go to its home directory as shown below. In it, you'll find prometheus.yml file which we need to modify.



Add the following gateway-actuator job inside the prometheus.yml. By default, prometheus includes a job named prometheus that can be accessed using url http://localhost:9090/metrics. Our gateway-actuator job's static config target points to our gateway application host and port. It also mentioned our actuator prometheus using metrics path /actuator/prometheus.


We can now run the prometheus from command prompt as shown below. Just type prometheus inside the prometheus home directory.


Next we can point out our browser to http://localhost:9090/metrics.


We can also point out to http://localhost:9090/graph to see the graph version of the metrics.


We can choose metrics http_server_requests_seconds_count and our gateway request count will be displayed:


Now we need to download and install grafana from its website here. The website also contains good documentation on how to get started using grafana. As mentioned in the getting started page, we can go to browser url http://localhost:3000/login and log in using default username and password admin admin. The grafana homepage is shown below after successfully logged in.


Next thing to do is to create a grafana data source by clicking below link.


In the Add Data Source page, choose Prometheus.


In the Configure Prometheus Data Source page, specify our prometheus host and port as shown below.


Next thing is to create dashboard by clicking link below:


In the New Dashboard page, add metrics that we want to see the graph. In this example we will add metrics http_server_requests_seconds_count as shown below.


The graph is displayed below:


The newly created dashboard is shown below:



Monday, April 12, 2021

Spring Boot Actuator

In this post, we will expose Spring Boot actuator in our previous gateway-server project. There are many endpoint actuator that is useful to monitor our microsevices, some of them are info and health. To enable actuator, we need to add the following dependency on our pom.xml.


The complete dependency in our pom.xml now looks like this.


Next in the application.properties we need to include exposed actuator endpoint. Here we include hystrix.stream, info, and health. As for actuator info, we add some custom information which are started with info key. And for actuator health, we will display a complete detail of information of the service using management.endpoint.health.show-details.


Let's now start the eureka-server, config-server, and gateway-server application. Once started, we can check the actuator info in browser as shown below.


Next point out to actuator health as shown below. Here we can confirm that the service status is UP. It also displays some other component information.


Lastly, we expose hystrix stream as shown below. However, one more step is needed by adding @EnableHystrix in Spring Boot application. This hystrix stream will be used by hystrix dashboard which we'll see on another post.



As a reference on actuator, this Spring documentation is a useful resource.

Friday, April 9, 2021

Microservices Architecture: Spring Cloud Eureka, Config, Gateway

Below is a common architecture of a microservice system that is implemented using Spring Cloud. In this picture we have a big box called eureka that contains four services, an api gateway, and a config service. Outside the box are clients that want to make requests and get responses from our system. To communicate with our system, those clients have to make request to api gateway. Api gateway will then follow up to the actual service. In the system, we have a centralized configuration that reside in the config service. Those three type of service (api gateway, micro services, config service) are registered in Eureka so that they can communicate easily. We have learned about Eureka in the previous post. Let's now implement all of this architecture using Spring Cloud.



Common Things

Each of the service above is implemented as a Spring Boot project. Below is how the projects look like in Eclipse. Here we have five projects. As the name implies, config-server, eureka-server, and gateway-server are self explanatory. We also have two eureka clients that will act as a service serving different purpose.


Each project shares the following maven pom.xml content. The spring-boot-starter-parent version is 2.4.4. They have dependency management to spring-cloud-dependencies version 2020.0.2. The other dependencies varies to different project.


Let's now take a look eureka-server project.

Eureka Server

The structure of the eureka-server project is shown below.


In the pom.xml we add dependency to spring-cloud-starter-netflix-eureka-server.


The Spring Boot application is shown below. Here we annotate it with @EnableEurekaServer to make it a Eureka server.


In application.properties file we change the server.port. We also set eureka.client.register-with-eureka and eureka.client.fetch-registry to false to prevent this application from registering itself. We also turned some logging off.


Next we'll see the config-server project.

Config Server

The structure of the config-server project is shown below.


In the maven pom.xml we add dependencies to spring-cloud-starter-netflix-eureka-client since this config-server project will be registered in Eureka. We also add spring-cloud-config-server since this project will act as config server. Lastly, we also add spring-boot-starter dependency.


In the Spring Boot application, we annotate it with @EnableConfigServer.


We also add several value in application.properties file. First, we set server.port and spring.application.name. We also set the Eureka server url through eureka.client.service-url.defaultZone. The next two properties spring.profiles.active and spring.cloud.config.server.native.searchLocations is used to locate configuration files. Here we say to Spring that we put configuration file in shared folder under project root folder.


Under shared folder we have one application.properties file that will be used by all services connecting to this config-server project. Here we specify the eureka.client.service-url.defaultZone and eureka.instance.hostname since they are common to all services.


Next we'll visit the actual services.

MicroServices

For simplicity and clarity we create two services here. Below is the project structure.



The maven pom.xml files have dependency to the following artifacts: spring-cloud-starter-netflix-eureka-client since these sevices will be registered under eureka. We also add dependency to spring-cloud-starter-config and spring-cloud-starter-bootstrap since we want these services to connect and fetch configuration from our config-server. Lastly we add spring-boot-starter-web dependency.


Next, we'll see the Spring Boot application class. Both classes are simple Spring Boot application annotated with @SpringBootApplication.


The eureka-client project also has a controller ServiceInstanceRestController. Requests to this controller is mapped to /client. The controller also has one method mapped to path variable /{applicationName}. The path variable {applicationName} could be any spring.application.name of projects registered in Eureka. We can call this service from browser using /client/eureka-client or /client/config-server to get information about the requested project.


The eureka-client-greeting project has one controller ServiceInstanceRestController. Requests to this controller is mapped to /greeting. The controller also has one method mapped to path variable /{greeting}. We can call this service from browser using /greeting/morning or /greeting/night and the result string will be returned and printed out to browser.


Next we'll see the application.properties file for both project. Here we can see that eureka-client project uses server.port 8181 and eureka-client-greeting uses server.port 8182. They also set the spring.application.name. This is the name that will be used when communicating to each other in eureka server.



Lastly, each service has a bootstrap.yml that contains url information of config-server. As we've seen above, the config-server listens to port 9898. This bootstrap.yml is called before application.properties so it is a good place to fetch data from config-server before the service starts.


Now we'll see the last part of puzzle, the api gateway.

API Gateway

The project structure of gateway-server project is shown below.


In the maven pom.xml we add dependencies to spring-cloud-starter-netflix-eureka-client since this api gateway will be registered under eureka server. We also add dependency to spring-cloud-starter-gateway itself. We also add dependency to spring-cloud-starter-config and spring-cloud-starter-bootstrap since we want api gateway to connect and fetch configuration from our config-server. We also add dependency to spring-cloud-starter-netflix-hystrix and spring-cloud-starter-circuitbreaker-reactor-resillience4j to have circuit breaker mechanism which we'll see later. Lastly we add dependency to spring-boot-starter. We use hystrix version 2.2.7.RELEASE for this project.


The Spring Boot application is just a simple class annotated with @SpringBootApplication.


We also create a fallback controller FallbackController which we'll use to display a message when a service is unavailable. Here we have two request mapping /client-fallback and /greeting-fallback that returns a message informing service unavailability. We'll see this request mapping later on the filters part of spring.cloud.gateway.routes in application.yml file.


Next we'll see the application.properties file. Here we set value for server.port and spring.application.name as we've done so far for all other projects. We also set value of management.endpoints.web.exposure.include and hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds as they are needed by hystryx.


Api gateway also has bootstrap.xml since it connects to config-server project.


Lastly it has application.yml where we can configure routes for our gateway. As shown below, there are two routes defined by id client and client-greeting.

The url for client is lb://eureka-client where lb means load balancer and eureka-client is the spring.application.name of the service. The predicates path means all request path started with /client/ should be redirected to eureka-client service. Note that we created request mapping /client in eureka-client project which match the predicate. In the filters we add CircuitBreaker and supply it with argument name client-fallback and fallbackuri forward:/client-fallback. Note that the name could be any name while fallbackuri is the request mapping of our FallbackController.

The url for client-greeting is lb://eureka-client-greeting where lb means load balancer and eureka-client-greeting is the spring.application.name of the service. The predicates path means all request path started with /greeting/ should be redirected to eureka-client-greeting service. Note that we created request mapping /greeting in eureka-client-greeting project which match the predicate. In the filters we add CircuitBreaker and supply it with argument name greeting-fallback and fallbackuri forward:/greeting-fallback. Note that the name could be any name while fallbackuri is the request mapping of our FallbackController.


Now let's run all of this stuff and see if it works. Run the following projects in order: eureka-server, config-server, gateway-server. Go to http://localhost:9876/ and check if our config-server and gateway-server is registered with eureka.


To check if fallback controller works, make request to gateway server http://localhost:9899/client/config-server. Here we ask for eureka-client project which is not up yet for now. The following error message will be displayed.


Same thing goes for eureka-client-greeting accessed from gateway http://localhost:9899/greeting/morning. Since the service is not up yet, error message will be shown instead.


Let's now run the eureka-client and eureka-client-greeting service. Check if they are registered with eureka as shown below.


Now refresh http://localhost:9899/client/config-server and http://localhost:9899/greeting/morning.




 

©2009 Stay the Same | by TNB