great! Construction of such micro-services architecture, it is too easy!

Author: Alexander Lukyanchikov      
Translator: Oopsguy
Original: dzone.com/articles/microservice-architecture-with-spring-cloud-and-do

[Editor's Note] how to use Spring Boot, Spring Cloud, Docker Netflix and some open source tools to build a micro-service architecture. By using Spring Boot, application examples and conceptual Spring Cloud Docker constructed to provide a starting point for understanding the common micro-service architecture model.

The code is available on GitHub, and is provided on the mirror Docker Hub. You only need a command to start the entire system.

https://github.com/sqshq/PiggyMetrics

I chose an old project as the basis for this system, which used to be the back end of a single application. This application provides the processing of personal finance, organize overhead income, savings management, statistical analysis and create a simple prediction function.

Service features

The entire application into three core micro service. They can all be deployed independently of the application, some business functions around the organization.

Account Services

It contains general input logic and user validation: income / expenses recorded savings and account settings.

Statistics Service

Calculation of the main statistical parameters, and capture time series for each account. It contains data point values ​​and the normalization period based currency. This data can be used to track the cash flow moving account of the life cycle.

Notification Service

Storing user contact information and notification settings (such as reminders and backup frequency). Arrangements for staff required information from other services collect and send e-mail subscription customers.

note

  • Each service has its own micro database, so there is no way to bypass the API to directly access persistent data.

  • In this project, I use MongoDB as the master database for each service. Have more than one kind of persistence architecture (polyglot persistence architecture) is also significant.

  • Room service (Service-to-service) communication is very simple: micro-services REST API using only synchronous communication. A common practice in reality the system is to use a combination of interactive style. For example, a GET request to retrieve synchronization data and performs asynchronous created using the method via a message broker (broker) / update operation, so as to release the coupling between the service and the message buffer. However, this gives us is the ultimate consistency.

Infrastructure Services

Distributed systems common pattern, can help us to describe the core service is how it works. Spring Cloud provides a powerful tool that can enhance the behavior of Spring Boot application to implement these patterns. I will briefly describe:

Configuration Service

Spring Cloud Config is a distributed system level centralized configuration of extension services. It uses the current support of local storage, Git and Subversion repositories such as pluggable layer (repository layer).

In this project, I used the native profile, it simply loads the configuration file from the local classpath. You can view the shared directory in a configuration service resource. Now, a service request notification when its configuration, the service response back to the configuration shared / notification-service.yml and shared / application.yml (shared among all client applications).

Clients use

Just use sprng-cloud-starter-config depends build Spring Boot application, will be automatically configured to perform other work.

Now your application does not require any embedded properties, only need to provide bootstrap.yml to the application name and configuration of service url:

spring:  
application:  
name: notification-service  
cloud:  
config:  
  uri: http://config:8888  
  fail-fast: true  

Use Spring Cloud Config, you can dynamically change the application configuration

For example, EmailService bean used @RefreshScope comment. This means that you can change the content and subject of the email, without having to rebuild and reboot notification service applications.

First, change the necessary attributes for the configuration server. Then, the notification service refresh request: curl -H "Authorization: Bearer # token #" -XPOST http://127.0.0.1:8000/notifications/refresh.

You can also use webhook to automate this process.

http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_push_notifications_and_spring_cloud_bus

note

  • Dynamic refresh, there are some restrictions. @RefreshScope not work together and @Configuraion class, and does not act on @Scheduled method.

  • fail-fast property means that if Spring Boot Configuration application can not connect to the service, will fail to start immediately. When you start the application all together, which is very useful.

  • The following important safety tips

Authorized Service

Partly responsible for the authorization is fully extracted to a separate server that provides OAuth2 token service to back-end resources. Authorization server for authorization and security between users within the perimeter machine communications.

In this project, I use the password credentials as the type of authorization (because it is used only by local application UI) and client credentials as a micro-authorized service authorized type of user authorization.

Spring Cloud Security provides convenient annotation and auto-configuration so that it can be easily implemented on the server side or client. You can find more information in the document, and check the configuration details in the authorization server code.

Authorization server code: https: //github.com/sqshq/PiggyMetrics/tree/master/auth-service/src/main/java/com/piggymetrics/auth

From a client point of view, everything is exactly the same as with the traditional session-based authorization. You can retrieve the Principal object from the request, check the user role and other expression-based access control and @PreAuthorize annotation content.

PiggyMetrics each client (account services, statistical services, notification services, and browser) has a range: Server for back-office services for the browser UI display. So we can avoid external access protection controller, for example:

@PreAuthorize("#oauth2.hasScope('server')")  
@RequestMapping(value = "accounts/{name}", method = RequestMethod.GET)  
public List<DataPoint> getStatisticsByAccountName(@PathVariable String name) {  
return statisticsService.findByAccountName(name);  
}   

API Gateway

As you can see, there are three core services. They are exposed to the external client API. In real systems, this number can grow very quickly, and the whole system will become very complicated. In fact, render a complex page may involve hundreds of service.

In theory, the client can directly send the request directly to each micro-services. But this is the way that challenges and limitations, if you need to know the addresses of all endpoints were executed http request for each piece of information, the merger will result to the client. Another problem is that this is not a web-friendly protocol may only be used in the back end.

Usually a better approach is to use the API gateway. It is the single entry point of the system, for by the route requests to appropriate back-end service or to process the request by calling a plurality of backend services and polymerization results. In addition, it can be used for authentication, insights, stress testing, test canary (canary testing), migration services, and actively transform the static response processing management.

Polymerization results: http: //techblog.netflix.com/2013/01/optimizing-netflix-api.html

Such an edge open source Netflix service, now with the Spring Cloud, we can use a @EnabledZuulProxy annotation to enable it. In this project, I used Zuul store static content (UI applications), and the request is routed to the appropriate micro-services. The following is based on a simple prefix (prefix-based) routing the notification service configuration:

zuul:  
routes:  
notification-service:  
    path: /notifications/**  
    serviceId: notification-service  
    stripPrefix: false  

This means that all requests to / notification will be routed to the beginning of the notification service. As you can see, there is no hard-coded addresses. Zuul service discovery mechanism used to locate and notify the service instance breakers and load balancers, as described below.

Service Discovery

Another common architectural pattern is service discovery. It allows automatic detection of the position of a network service instance, since the automatic extension and upgrading failure, it may be dynamically assigned address.

The key part of the service discovery is registered. I use Netflix Eureka conduct this project, when the client is responsible for determining the service instance can use (use registration server) cross-platform location and load balancing requests, Eureka client is a good example of pattern discovery.

Use Spring Boot, you can use spring-cloud-starter-eureka-server dependent, @ EnabledEurekaServer notes and simple configuration to easily build Eureka property registry (Eureka Registry).

Use @EnabledDiscoveryClient annotations and bootstrap.yml with the name of the application to enable client support:

spring:  
application:  
name: notification-service  

Now, when the application starts, it will register with the Eureka server and provide metadata, such as the host and port health indicator URL, home and so on. Eureka receive heartbeat messages from each subordinate instance of a service. If the heartbeat fails exceeds the configured schedule, the examples deleted from the registry.

In addition, Eureka also offers a simple interface, you can track the number of running instances of service and available through it: http: // localhost: 8761

Load balancing, circuit breakers and Http Client

Netflix OSS provides another set of great tools.

Ribbon

Ribbon is a client load balancer, HTTP can be well controlled and TCP client behavior. Compared with traditional load balancers, each line calls do not need an extra jump - you can directly contact the desired service.

It found Spring Cloud services are integrated and can be out of the box. Eureka client provides a dynamic list of available servers, Ribbon can thus balance between them.

Hystrix

Hystrix is ​​one implementation mode of the circuit breaker, which can be controlled by the network access failures and delay dependent. The central idea is to stop the cascading failures in a distributed environment with a large number of micro service. This helps to quickly fail and recover as soon as possible - in a self-healing fault-tolerant system is very important.

In addition to circuit breaker control, MAMMALIA, in use, you can add a backup method in case of failure of the primary command, which will be called to get the default values.

In addition, Hystrix generate the results of each command and latency metrics, we can use it to monitor the behavior of the system.

Feign

Feign is a declarative HTTP client, seamless integration with the Ribbon and Hystrix. In fact, by a spring-cloud-starter-feign dependency and @EnabledFeignClients annotations, you can use a set of load balancing, circuit breakers and HTTP clients, and comes with a reasonable default configuration.

The following are examples of account services:

@FeignClient(name = "statistics-service")  
public interface StatisticsServiceClient {  
@RequestMapping(method = RequestMethod.PUT, value = "/statistics/{accountName}", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)  
void updateStatistics(@PathVariable("accountName") String accountName, Account account);  
}   
  • All you need is an interface

  • You can share @RequestMapping section between Spring MVC controller method and Feign

  • The above example specifies only the service required ID - statistics-service, thanks to Eureka automatic discovery (but apparently you can use a specific URL to access any resource).

Monitoring dashboard

In this project configuration, Hystrix each micro-services through Spring Cloud Bus (via AMQP broker) will push the index to Turbine. Monitoring project using only a small Spring Boot application Turbine and Hystrix dashboard.

Let us look at the system behavior under load: Response Account service call statistics service and a change in its analog delay. Response timeout threshold set to 1 second.

Log Analysis

Centralized logging is very useful when trying to find the problem in a distributed environment. Elasticsearch, Logstash and Kibana technology stack allows you to easily search and analyze your logs, utilization and network activity data. In another project I have been ready Docker configuration.

Safety

Advanced security configuration is beyond the scope of this conceptual project. In order to more realistically simulate real system, consider using https and JCE content encryption key store properties to the micro-service password and configure the server (for details, see the documentation).

Infrastructure Automation

The deployment of micro-services much more complex than the process to deploy a single application, because they are interdependent. Has fully automated basis set is very important. We can receive the following benefits by way of continuous delivery:

  • At any time publishing capabilities of the software.

  • Any building could eventually become a release.

  • Construction of a workpiece (artifact) once deployed, as necessary.

This is a simple continuous delivery workflow, implemented in this project:

In this configuration, Travis CI for each successful Git push to create the image tag. Therefore, each micro Docker Hub service on the latest, there will be a mirror, but a mirror image of the older Git submitted using the hash mark. If necessary, you can easily deploy any of them, and quickly rolled back.

How to run all?

It's really simple, I recommend that you try it. Remember that you will want to start 8 Spring Boot application, four MongoDB instance and RabbitMq. Ensure that there is 4GB of memory on your machine. You can always important services through the gateway, registry, configuration, authentication and account service center operations.

Before running

  • Installation and Docker Docker Compose.

  • Configuration environment variable: CONFIG_SERVICE_PASSWORD, NOTIFICATION_SERVICE_PASSWORD, STATISTICS_SERVICE_PASSWORD, ACCOUNT_SERVICE_PASSWORD, MONGODB_PASSWORD

Mode of production

In this mode, all the latest mirrors are pulled from the Hub Docker. Copy docker-compose.yml and perform docker-compose up -d can be.

Development model

If you want to build your own image (for example, some modifications in the code), you need to clone all warehouse (repository) and use Mavne build artifacts (artifact). Then, run the docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d

docker-compose.dev.yml inherited docker-compose.yml, comes with additional configuration, the mirror can be built locally, and exposed to all container ports in order to facilitate development.

Important endpoints (Endpoint)

  • localhost: 80 - Gateway

  • localhost: 8761 - Eureka dashboard

  • localhost: 9000 - Hystrix dashboard

  • localhost: 8989 - Turbine stream (Hystrix dashboard source)

  • localhost: 15672 - RabbitMq Management

note

All Spring Boot applications need to run the configuration server to start. Thanks to the Spring Boot fail-fast property and docker-compsoe the restart: always options, we can start all containers simultaneously. This means that all depend on the container will attempt to restart until the configuration server up and running so far.

In addition, service discovery mechanisms take some time after all the applications start. In the example before, the Eureka server and client in its local cache has the same metadata, services are not available for any client discovery, it may take three beats. The default heartbeat interval of 30 seconds.

Published 50 original articles · won praise 1706 · Views 2.22 million +

Guess you like

Origin blog.csdn.net/zl1zl2zl3/article/details/105301323