Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Spring Cloud to build a micro-service architecture

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Editor to share with you how to use Spring Cloud to build micro-service architecture, I believe most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's learn about it!

The core of micro-service architecture pattern is how to identify the boundary of service and design reasonable micro-service.

However, if we want to apply the micro-service architecture to the production project, and can play an important role in the architecture model, we need the support of the micro-service framework.

In the Java ecosystem, the most widely used micro-service framework is the integration of Netflix OSS and Spring Cloud.

It includes:

Spring Cloud Config: a configuration management tool that supports the use of Git to store configuration content, externalized storage of application configuration, refresh of client configuration information, encryption / decryption of configuration content, etc.

Spring Cloud Netflix: Netflix OSS has been integrated.

These include:

Eureka: service governance component, including service registry, service registration and discovery.

Hystrix: container management component that implements circuit breaker mode and provides powerful fault tolerance in case of delay or failure of dependent services.

Ribbon: the service invocation component of the client load balancer.

Feign: a declarative service invocation component based on Ribbon and Hystrix.

Zuul: a gateway component that provides intelligent routing, access filtering and other functions.

Archaius: externalize the configuration component.

Spring Cloud Bus: event, message bus.

Spring Cloud Cluster: election algorithm and implementation of general state mode for ZooKeeper, Redis, Hazelcast, Consul.

Spring Cloud Cloudfoundry: integrated support with Pivotal Cloudfoundry.

Spring Cloud Consul: a service discovery and configuration management tool.

Spring Cloud Stream: message-driven microservices implemented through Redis, Rabbit, or Kafka.

Spring Cloud AWS: simplify and integrate Amazon Web Service.

Spring Cloud Security: a security toolkit that provides repeaters for requests to OAuth3 clients in the Zuul agent.

Distributed tracking implementation of Spring Cloud Sleuth:Spring Cloud applications, which can integrate Zipkin.

Spring Cloud ZooKeeper: a ZooKeeper-based component for service discovery and configuration management.

The basic components of Spring Cloud Starters:Spring Cloud are the basic dependency modules of Spring Boot-style projects.

Spring Cloud CLI: a Spring Boot CLI plug-in for quickly creating Spring Cloud applications in Groovy.

Service governance

When there are more and more micro-services in a system, we need to govern the services, provide a unified service registry, and then provide the function of discovering services under its framework.

This avoids the configuration of multiple microservices and the coupling between microservices and clients.

Spring Cloud Eureka is a wrapper for Netflix Eureka to implement service registration and discovery.

The Eureka server is the service registry, which supports highly available configurations. It relies on strong consistency to provide good service instance availability and supports cluster mode deployment.

The Eureka client is responsible for handling service registration and discovery. The client service is embedded in the client application code through annotation and parameter configuration.

When running the application, the Eureka client registers its own services with the registry and periodically sends a heartbeat to update its service lease.

Build a service registration center

The service registry is an independently deployed service (you can think of it as a micro service as well), so you need to create a separate project for it and add Eureka dependencies to pom.xml:

Org.springframework.cloud spring-cloud-starter-eureka-server

Create a Spring Boot Application:

@ EnableEurekaServer @ SpringBootApplication public class Application {public static void main (String [] args) {new SpringApplicationBuilder (Application.class) .web (true) .run (args);}}

Register a service provider

To enable the micro service you write to register with the Eureka server, you need to add the @ EnableDiscoveryClient annotation to the Spring Boot Application of the service so that the Eureka server can discover the service.

Of course, you also need to add related dependencies to the pom.xml file:

Org.springframework.cloud spring-cloud-starter-eureka

At the same time, we also need to name the service and specify an address. This information can be configured in the application.properties configuration file:

Spring.application.name=demo-service eureka.client.serviceUrl.defaultZone= http://localhost:1111/eureka/

Note: Spring is more recommended to use yml files to maintain the configuration of the system, yml files can reflect the hierarchical relationship of the configuration section, the performance is better than the simple key-value form.

If you use the Spring Cloud Config discussed later, the client configuration file must be named bootstrap.properties or bootstrap.yml.

The yml file that is the same as the above configuration is configured as:

Spring: application: name: demo-service eureka: client: serviceUrl: defaultZone: http://localhost:1111/eureka/

Service discovery and consumption

Under the micro-service architecture, many micro-services may play a dual role:

On the one hand, it is a service provider.

On the other hand, it may be the consumer of the service.

Microservices registered in Eureka Server may be consumed by other services. At this point, it is equivalent to creating a client of another service in the service and initiating a call to the service through RestTemplate.

In order to better improve performance, Ribbon can be introduced into the client side of the service as a client-side load balancing.

Now suppose we want to create a service consumer demo-consumer for demo-service. The consumer itself is a Spring Boot microservice and can also be registered with an Eureka server.

At this point, you need to add the dependency of Eureka and Ribbon to the pom.xml of the service:

Org.springframework.cloud spring-cloud-starter-eureka org.springframework.cloud spring-cloud-starter-ribbon

Then inject RestTemplate into the main application class ConosumerApplication and introduce the @ LoadBalanced annotation to enable the client load balancer:

@ EnableDiscoveryClient @ SpringBootApplication public class ConsumerApplication {@ Bean @ LoadBalanced RestTemplate restTemplate () {return new RestTemplate ();} public static void main (String [] args) {SpringApplication.run (ConsumerApplication.class, args)}}

Suppose the client code that consumes the demo-service is written in one of the Controller of the demo-consumer service:

@ RestController public class ConsumerController {@ Autowired RestTemplate restTemplate; @ RequestMapping (value = "/ demo-consumer", method = RequestMethod.Get) public String helloConsumer () {return restTemplate.getForEntity ("http://demo-service/demo", String.class) .getBody ();}}

Through RestTemplate, you can make a consumption call to demo-service.

Declarative service invocation

Micro-service invocation and fault-tolerant protection can be achieved through Ribbon and Hystrix, but Spring Cloud also provides another simpler way of declarative service invocation, namely Spring Cloud Feign.

Feign is actually a further encapsulation of Ribbon and Hystrix. With Feign, we can bind the interface (REST API) to the service provider simply by creating an interface and configuring it in annotation.

Suppose we have three services:

Notification Service

Account Service

Statistics Service

The dependencies between services are shown in the following figure:

To use Feign to complete declarative service calls, you need to create a Client in the service as the caller.

Client invokes the registered corresponding service through Eureka Server, which decouples the services.

The structure is shown in the following figure:

In order to use Feign, you need to add the following dependencies to the pom.xml file of the corresponding microservice:

Org.springframework.cloud spring-cloud-starter-feign

At the same time, you also need to add the @ EnableFeignClients annotation to the consumed microservice Application.

For example, in the application class of the Statistics service:

@ SpringBootApplication @ EnableDiscoveryClient @ EnableFeignClients public class StatisticsApplication {public static void main (String [] args) {SpringApplication.run (StatisticsApplication.class, args);}}

Because the Account service needs to invoke the Statistics service, you need to add the corresponding Client interface to the Account service project:

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);}

The updateStatistics () method of the StatisticsServiceClient interface invokes the REST service with URI of / statistics/ {accountName} and the HTTP verb is put.

This service corresponds to the saveStatistics () method in the StatisticsController class in Statistics Service:

@ RestController public class StatisticsController {@ Autowired private StatisticsService statisticsService; @ RequestMapping (value = "/ {accountName}", method = RequestMethod.PUT) public void saveStatistics (@ PathVariable String accountName, @ Valid @ RequestBody Account account) {statisticsService.save (accountName, account);}}

In Account services, if you want to invoke a Statistics service, you should invoke it through the StatisticsServiceClient interface.

For example, if an AccountServiceImpl in an Account service wants to call the updateStatistics () method, it can inject the StatisticsServiceClient interface through @ autowired in the implementation of the class:

Service public class AccountServiceImpl implements AccountService {@ Autowired private StatisticsServiceClient statisticsClient; @ Autowired private AccountRepository repository; @ Override public void saveChanges (String name, Account update) {/ /. StatisticsClient.updateStatistics (name, account);}}

The invocation of the Notification service to the Account service is done the same way.

Service fault-tolerant protection

In the micro-service architecture, there may be dependencies between micro-services, for example, Notification Service calls Account Service,Account Service to invoke Statistics Service.

In real products, calls between microservices are more common. If the upstream service fails, it may lead to the spread of the fault because of the dependency, and eventually lead to the paralysis of the whole system.

Spring Cloud Hystrix implements fault-tolerant protection of services by implementing circuit breaker (Circuit Breaker) mode and thread isolation.

Still referring to the previous example, the micro services of the system now include:

Upstream service: demo-service

Downstream service: demo-consumer

Eureka server: eureka-server

Assuming that the upstream service may fail, in order to ensure the robustness of the system, it is necessary to add fault-tolerant inclusion function to the downstream service.

First, you need to add a dependency on Hystrix to the demo-consumer service:

Org.springframework.cloud spring-cloud-starter-hystrix

Then add @ EnableCircuitBreaker to the application class of demo-consumer to turn on the circuit breaker function:

EnableCircuitBreaker @ EnableDiscoveryClient @ SpringBootApplication public class ConsumerApplication {@ Bean @ LoadBalanced RestTemplate restTemplate () {return new RestTemplate ();} public static void main (String [] args) {SpringApplication.run (ConsumerApplication.class, args)}}

Note: SpringCloud provides @ SpringCloudApplication annotations to simplify the code as above. This comment actually contains the three annotations mentioned earlier.

The definition of the @ SpringCloudApplication annotation is as follows:

Target (ElementType.TYPE) @ Retention (RetentionPolicy.RUNTIME) @ Documented @ Inherited @ SpringBootApplication @ EnableDiscoveryClient @ EnableCircuitBreaker public @ interface SpringCloudApplication {}

Next, we need to introduce a new service class to encapsulate the circuit breaker protection function provided by Hystrix, mainly to define the callback logic to be executed when a fault occurs, that is, the fallbackMethod specified in the code:

@ Service public class ConsumerService {@ Autowired RestTemplate restTemplate; @ HystrixCommand (fallbackMethod = "consumerFallback") public String consume () {return restTemplate.getForEntity ("http://demo-service/demo", String.class). GetBody ();} public String consumerFallback () {return" error ";} @ RestController public class ConsumerController {@ Autowired ConsumerService consumerService RequestMapping (value = "/ demo-consumer", method = RequestMethod.Get) public String helloConsumer () {return consumerService.consume ();}}

Service monitoring

The micro-service architecture decomposes the granularity of services fine enough, which not only makes it flexible and independent enough, but also brings management and monitoring challenges, and the dependence between services becomes more and more complex. Therefore, the monitoring of service health and operation indicators becomes very important.

Hystrix provides various metrics information that Dashboard uses to monitor Hystrix. In order to monitor the microservices of the entire system, we need to set up a Spring Boot microservice for Hystrix Dashboard.

In the pom file of the service project, add the following dependencies:

Org.springframework.cloud spring-cloud-starter-hystrix org.springframework.cloud spring-cloud-starter-hystrix-dashboard org.springframework.cloud spring-cloud-starter-actuator

The Application class of the service needs to add @ EnableHystrixDashboard to enable the HystrixDashboard feature.

At the same time, you may need to modify the application.properties configuration file according to the actual situation, such as selecting an available port number, and so on.

If you want to monitor the cluster, you need to join Turbine.

API Gateway

In theory, the client can send requests directly to each microservice. But there are challenges and limitations in this approach. Callers need to know the addresses of all endpoints, execute http requests for each piece of information separately, and then merge the results into the client.

Generally speaking, systems with micro-service architecture model adopt a separate architecture of front and back end. To clearly separate the boundary between the front end and the back end, we can usually define a more coarse-grained Open Service specifically for front-end consumers.

These Open Service are external RESTful API services, which can be routed and load balanced through F5, Nginx and other network devices or tools, and exposed to external client calls (note that calls between internal micro services do not need to go through Open Service).

This kind of public Open Service is often called edge service (edge service).

If we need to develop and implement the service operation and maintenance of these Open Service, it will become more and more difficult with the increasing scale of the system.

For example, when new micro-services are added or the IP address changes, operators are required to manually maintain these routing rules and service instance lists.

For example, for all vertically separated micro-services, there will inevitably be crosscutting concerns for reuse, such as user authentication, authorization or signature verification.

We cannot add the same functionality to all microservices because it results in redundancy of crosscutting concerns.

The solution is to introduce an API gateway (API Gateway). It is a single entry point to the system that processes the request by routing the request to the appropriate back-end service or by invoking multiple back-end services and aggregating the results.

In addition, it can be used for authentication, insights, stress testing, canary testing (canary testing), service migration, static response processing, and active transformation management.

The solution that Spring Cloud provides for API gateways is Spring Cloud Zuul, which is a wrapper for Netflix Zuul.

Routing rules and Service instance maintenance

The way Zuul solves the maintenance of routing rules and service instances is through Spring Cloud Eureka.

API Gateway itself is a Spring Boot service, which itself is registered as an application under the governance of Eureka services, and it gets instance information of all other micro services from Eureka.

This design is in line with DRY principles, because Eureka already maintains a set of service instance information, which Zuul reuses directly without human intervention.

For routing rules, Zuul creates a route map by default using the service name as ContextPath. Basically, this route mapping mechanism can meet the routing requirements of the micro-service architecture.

If some special configuration is required, Zuul also allows us to customize routing rules, which can be defined by creating PatternServiceRouteMapper in the Application class of the API gateway.

Crosscutting concern

Business logic such as authorization authentication and signature verification is not directly related to the business logic that microservice applications deal with. We call these functions that may span multiple microservices "crosscutting concerns". These crosscutting concerns are often invoked as "decorating" functions before and after the service method.

Spring Cloud Zuul provides a set of filter mechanisms that allow developers to create various filters and specify which rules need to be executed for requests.

The custom filter inherits from the ZuulFilter class. For example, we require the request sent by the client to verify whether the accessToken parameter is included in the request before routing.

If there is a route, otherwise it is rejected and a 401 Unauthorized error is returned, you can define the AccessFilter class:

Public class AccessFilter extends ZuulFilter {private static Logger log = LoggerFactory.getLogger (AccessFilter.class); @ Override public String filterType () {return "pre"} @ Override public int filterOrder () {return 0;} @ Override public boolean shouldFilter () {return true;} @ Override public Object run () {RequestContext ctx = RequestContext.getCurrentContext () HttpServletRequest request = ctx.getRequest (); log.info ("send {} request to {}", request.getMethod (), request.getRequestURL (). ToString ()); Object accessToken = request.getParameter ("accessToken"); if (accessToken = = null) {log.warn ("access token is empty"); ctx.setSendZuulResponse (false); ctx.setResponseStatusCode (401); return null } log.info ("access token ok"); return null;}}

For this custom filter to take effect, you also need to create a specific Bean in the Application of the Zuul service:

@ EnableZuulProxy @ SpringCloudApplication public class ZuulApplication {public static void main (String [] args) {new SpringApplicatonBuilder (ZuulApplication.class) .web (true) .run (args);} @ Bean public AccessFilter accessFilter () {return new AccessFilter ();}}

Zuul provides a total of four filters:

Pre filter

Routing filter

Post filter

Error filter

The following figure is from the official website, which shows the lifecycle and filtering process of client requests arriving at the Zuul API gateway:

When adding the dependency of Zuul through starter, it includes the dependency of spring-cloud-starter-hystrix and spring-cloud-starter-ribbon module, so Zuul itself has the service fault tolerance function of thread isolation and circuit breaker, as well as client load balancing.

However, if we use the mapping relationship between path and url to configure routing rules, the requests forwarded by routes will not be wrapped in HystrixCommand, so this kind of routing has no service fault tolerance and client load balancing.

Therefore, when using Zuul, you should try to use the combination of path and serviceId to configure the route.

Distributed configuration center

Why introduce a distributed configuration center? A microservice requires at least one profile. How to manage the profiles scattered among microservices? If microservices use different technology stacks, how to unify the configuration of microservices?

Microservices are deployed in different nodes, so obviously we can't manage the configuration of distributed nodes in a stand-alone machine. This is the purpose of introducing Spring Cloud Config.

Spring Cloud Config provides both server and client support. The server is a stand-alone micro-service that can also be registered with the Eureka server.

Every microservice that needs to use a distributed configuration center is a client of Spring Cloud Config.

The default implementation of Spring Cloud Config is based on the Git repository, which can be versioned and cached through a local Git library.

Spring Cloud Config is not limited to systems developed based on Spring Cloud, but programs that can be developed in any language and supports custom implementations.

Configure the central server

As the configuration center server, Spring Cloud Config Server provides the following functions:

Update the copy of the Git repository when pulling the configuration to ensure that the result is *.

Support rich data structure, yml,json,properties and so on.

Service discovery can be realized with Eureke, and configuration push updates can be realized with cloud bus.

The configuration store is based on the Git repository and can be versioned.

Simple and reliable, with a wealth of supporting programs.

To build a Config service, you need to add the following dependencies:

Org.springframework.cloud spring-cloud-config-server

The Application class of the service needs to be annotated with @ EnableConfigServer:

@ SpringBootApplication @ EnableConfigServer public class ConfigApplication {public static void main (String [] args) {SpringApplication.run (ConfigApplication.class, args);}}

The basic information of the configuration service and the information of the Git repository are placed in the application.yml file:

Spring: cloud: config: server: git: uri: http://localhost/workspace/springcloud-demo username: user password: password server: port: 8888 security: user: password: ${CONFIG_SERVICE_PASSWORD}

Git Library and configuration Service

After configuring the information for the Git server and the Git library in the Config service, we can submit the configuration file in the Git library.

The name of the configuration file stored in the Git library and the branch name (default is master branch) make up the URI that accesses the Config service.

If a service is a Notification service, its configuration file on the configuration center server is notification-dev.yml, as follows:

DevMode: true spring: application: name: notification jdbc: host: localhost port: 3306 user: root password: 123456 logging: file: demo

Configure the central client

The micro-services that need to read the server information of the configuration center are all the clients of the configuration center. In order to read the information of the configuration server, these micro-services need:

Add dependencies to spring-cloud-starter-config in pom.

Configure the config-server location in bootstrap.properties or bootstrap.yml to get the configuration.

For example, the configuration of the Account service is managed by Spring Cloud Config. Under its resources directory, the bootstrap.yml configuration file is provided, as follows:

Spring: application: name: account-service cloud: config: uri: http://config:8888 fail-fast: true password: ${CONFIG_SERVICE_PASSWORD} username: user

Note that in addition to configuring the name of the Account service application, the configuration file mainly supports the application to obtain configuration server-side information.

The configuration information of the micro-service itself is uniformly placed in the file of the configuration center server and managed by the Git library.

For example, the detailed configuration of the Account service is in the account-dev.yml file on the server side of the configuration center:

Security: oauth3: client: clientId: account-service clientSecret: ${ACCOUNT_SERVICE_PASSWORD} accessTokenUri: http://auth-service:5000/uaa/oauth/token grant-type: client_credentials scope: server spring: data: mongodb: host: account-mongodb username: user password: ${MONGODB_PASSWORD} database: piggymetrics port: 27017 server: context-path: / accounts port: 6000

Spring Cloud Config implements distributed configuration management through Git. When the configuration information of the configuration center server changes, each micro-service as the configuration client will submit pull updates to the Git library to obtain * * configuration information.

Of course, Spring Cloud Config can also use the SVN library for configuration management and supports simple local file system storage.

At this point, you need to set spring.profiles.active to native and set the path to the search profile. If the path is not configured, it is searched under the src/main/resources directory by default.

The configuration files are as follows:

Spring: cloud: config: server: native: search-locations: classpath:/shared profiles: active: native

The search path is placed in the shared directory under classpath, so in the code, the directory is resources/shared.

If you use a local file system to manage configuration files, distributed configuration management and version management cannot be supported, so on production systems, Git libraries are recommended.

The above is all the content of the article "how to use Spring Cloud to build a micro-service architecture". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report