SpringCloud
1, Service registration and discovery
Eureka(AP)
- Service registration is relatively fast, because there is no need to wait for the registration information to replicate to other nodes, and there is no guarantee that the registration information will replicate successfully;
- When the data is inconsistent, although the registration information on A and B is not the same, each Eureka node can still provide external services normally. This time, if request A fails to find the service information, request B can find it. This guarantees availability at the expense of consistency.
Nacos
/** *1 - how to use Nacos as configuration center to manage configuration *1. Dependence * <dependency> cloud</grouId> * <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> * </dependency> *2. Create a bootstrap.properties : * spring.application.name=gulimall-coupon * spring.cloud.nacos.config.server-addr=127.0.0.1:8848 *3. You need to add a (Data Id / data set) normal to the configuration center by default- coupon.properties (application name. properties) *4. Dynamic acquisition configuration *RefreshScope: get and refresh the configuration dynamically *@ Value("${name of configuration item}"): get configuration *If the same item is configured in the nacos configuration center and the local configuration file -- the configuration of nacos configuration center is preferred *2 - details *1. Namespace: configure isolation: *Default: public (reserved space): all new configurations are in the public space by default; *1. Development, test and production: use namespace to realize environment isolation *Note: in bootstrap.properties Which namespace is required for configuration * spring.cloud.nacos . config.namespace=XXXXXXXXXXXXXXXXXXXXXXXXXXX (configuration management ID) *2. Each microservice is configured separately from each other. Each microservice creates its own namespace and only loads all configurations under its own namespace *2. Configuration set: the set of all configurations *3. Configuration set ID: *Data ID -- similar file name *4. Configuration group: *All configuration sets by default belong to: DEFAULT_GROUP;----1111,618,1212 *Configure configuration groups: spring.cloud.nacos.config.group=1111 ---Configure grouping * *Each microservice creates its own namespace and uses configuration grouping to distinguish environment - dev\test\prod *3 - load multiple configuration sets at the same time *1. Any configuration information of microservice can be placed in the configuration center in any configuration file *2. Only in bootstrap.properties Describe which configuration files in the configuration center can be loaded * 3.@Value,@ConfigurationProperties *In the past, any method of SpringBoot to get the value from the configuration file could use *The configuration center has the priority to use the configuration center */
Conul(CP)
- Service registration is a little slower than Eureka, because Consul's reft protocol requires that more than half of the nodes write successfully before the registration is successful;
- When the Leader passes, the entire Consul is not available during the re-election. Strong consistency is guaranteed but cocoa use is sacrificed.
##Launch consumer in developer mode/ localhost:8500 consul agent -dev -client=0.0.0.0
<!--springcloud Provided set in consul Service discovery for--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul</artifactId> </dependency> <!--actuator Health examination of--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-actuator</artifactId> </dependency>
#Consumer service registration configuration cloud: consul: host: 127.0.0.1 #Host address of consumer post: 8500 #Port number of the server discovery: #Need to register register: true #Registered instance ID (unique flag) instance-id: ${spring.application.name}-1 #Name of the service service-name: ${spring.application.name} #Request port for service port: ${server.port} #Specify to enable ip address registration prefer-ip-address: true #Request ip of current service ip-address: ${spring.cloud.client.ip-addrss}
Zookeeper
2, Remote call
RestTemplate
Feign
- Feign is a declarative and templated HTTP client developed by Netfix
- Feign comes with Ribbon load balancing (you can modify the load balancing policy in the way of Ribbon)
1. Import dependency
<!--SpringCloud Integrated openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2. Configure call interface
/** * Created with IntelliJ IDEA * User: GHYANG * Date: 2020-06-13 * Description:Declare the name of the microservice to be called */ @FeignClient(name="service-product") public interface ProductFeignClient{ /** *Configure the microservice interface to be called (directly copy the controller header information) */ @RequestMapping(value="/product/{id}",method=RequestMethod.GET) public Product findById(@PathVariable("id") Long id); }
3. Activate Feign on the startup class
@EnableFeignClients
4. Call remote microservice through automatic interface
//Inject feign instance @Autowired ProductFeignClient productFeignClient; //Called in method body productFeignClient.findById();
5. Other configurations
#Configure the output of the fegin log #NONE: do not output log #BASIC: applicable to production environment tracking problems #HEADERS: record the request and corresponding header information on the basis of BASIC #FULL: record all feign: client: config: service-product: #Service name to call loggerLevel: FULL
3, Caching mechanism
Redis+Reidsson
-
Cache penetration: empty result cache
-
Cache avalanche: set random expiration time
-
Cache breakdown: add lock
//As long as it is the same lock, all threads that need the lock can be locked
//1-synchronized (this): all components of spring boot are singleton in the container
//1 - after getting the lock, we should go to the cache again to confirm it. If not, we need to continue the query
//2 - local lock: synchronized, JUC (lock). In the distributed situation, if you want to lock all, you must use the distributed lock, and each service of the local lock will execute the business once;
//Use map to simulate local cache private Map<String,Object> cache = new HashMap<>(); //Simulation mode Map<String, List<Catelog2Vo>> catalogJson = (Map<String, List<Catelog2Vo>>) cache.get("catalogJson"); if(cache.get("catalogJson") == null){ //Cache is empty //Call business and cache cache.put("catalogJson",parent_cid); } return catalogJson;
//Using Redisson @ResponseBody @GetMapping("/hello") public String hello(){ //1 - obtain a lock as long as the lock name is the same, so as to realize distributed RLock my_lock = redisson.getLock("my_lock"); //2-locking my_lock.lock();//Blocking wait, the default lock is 30s //2 -- automatic renewal of lock. If the business is too long, a new 30s will be automatically added to the lock during operation. There is no need to worry about the long business time, and the lock will automatically expire and be deleted //3 -- as long as the lock business is completed, the current lock will not be renewed, and the lock will not be unlocked manually in time. By default, the lock will be automatically deleted after 30s // My_ lock.lock (10, TimeUnit.SECONDS ); / / 10 seconds automatic unlocking. The automatic unlocking time should be greater than the execution time of the business //Question: my_lock.lock(10, TimeUnit.SECONDS : will not renew automatically after the lock time /** * 1-If we pass the lock timeout, we will send it to redis to execute the script to occupy the lock. The default timeout is the time we specify * 2-If we don't specify a lock timeout, use 30 * 1000 {lockwatchdog timeout's default time} * As long as the lock is occupied successfully, a timing task will be started {reset the expiration time of the lock, and the new expiration time is the default time of the watchdog} * internalLockLeaseTime{Watchdog time} / 3 -- > 10s no interval of 10s automatic renewal, renewal of 30s * * Best practice: * Use my_ lock.lock (10, TimeUnit.SECONDS ); the whole renewal operation is omitted, manual unlocking and watchdog mechanism is not used */ try { System.out.println("Lock successfully-Conduct business"+Thread.currentThread().getId()); Thread.sleep(20000); }catch (Exception e){ }finally { //3 - if the unlocking code is not running, will the redisson deadlock System.out.println("Release lock"+Thread.currentThread().getId()); my_lock.unlock(); } return "hello"; }
-
redis read / write lock:
-
Read / write lock - ensure to read the latest data. During modification, the write lock is an exclusive lock (exclusive lock, exclusive lock), and the read lock is a shared lock
- You have to wait until the write lock is released
- Read lock + read lock: it is equivalent to no lock, concurrent read. It will only be recorded in redis. All current read locks will be locked successfully at the same time
- Write lock + read lock: wait for the write lock to release
- Write lock + write lock: blocking mode
- Read lock + write lock: there is a read lock. Writing also has to wait
- As long as there is writing, we must wait
4, Load balancing
Ribbon
1. Service call
- eureka integrates ribbon internally (spinning cloud also integrates ribbon internally for Consul, the same usage)
- When creating RestTemplate, declare @ LoadBalanced
- Use restTemplate to call remote service: no need to splice the URL of microservice and replace the IP address with the service name to be requested
2. Load balancing
Load balancing strategy: polling (default), random, Retry, weight
3. Retry mechanism
Introducing spring's retry dependency
<dependency> <groupId>org.springframework.retry</groupId> <artfactId>spring-retry</artfactId> </dependency>
Retry configuration of ribbon
service-product: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule ConnectTimeout: 250 # Connection timeout of Ribbon ReadTimeout: 1000 # Data read timeout of Ribbon OkToRetryOnAllOperations: true # Retry all operations MaxAutoRetriesNextServer: 1 # Number of retries to switch instances MaxAutoRetries: 1 # Number of retries to the current instance
Nginx F5
-
nginx is a high-performance HTTP and reverse proxy server, which is used as HTTP soft load balancer by many websites. nginx can also be used as a static resource server
-
Load balancing algorithm: polling, weight, ip binding
#Polling configuration upstream product{ service 127.0.0.1:8002; #Server 1 service 127.0.0.1:8081; #Server 2 } #Extension: the following is static resource configuration server{ listen 80; #Port number monitored server_name gulimall.com #Monitored domain name location /static/{ #Matching url root /usr/share/nginx/html; #Match the actual resource path accessed successfully } } #Extension: the following are reverse agents server{ listen 80; #Listen to port 8080 server_name gulimall.com #Monitored domain name location /{ #Intercept the request heard by the supervisor proxy_pass http://gulimall; #The request is forwarded to the system gateway where the gulial is the same as the server in the upstream below } } #upstream xxx: indicates that the load balancing server is the upstream server upstream gulimall{ server 192.168.252.1:88 #Path of actual request }
#Weight configuration #upstream xxx: indicates that the load balancing server is the upstream server upstream gulimall{ server 192.168.252.1:88 weight=2; #Actual gateway and weight value server 192.168.252.1:89 weight=3; #Actual gateway 2 and weight value }
#ip binding configuration #upstream xxx: indicates that the load balancing server is the upstream server #Matching principle: according to the IP address of the client, Through the hash function calculation, a numerical value is obtained, which is used to model the size of the server list. The result is the serial number of the server to be accessed by the customer service end. The source address hash method is used for load balancing. For the client with the same IP address, when the back-end server list is unchanged, it will map to a back-end server for access each time. upstream gulimall{ server 192.168.252.1:88; #Actual gateway server 192.168.252.1:89; #Actual gateway 2 ip_hash; }
5, Service fuse
-
Avalanche effect: there is a strong dependence between services, and faults will spread, causing chain reaction, which will have disastrous consequences for the whole microservice system.
-
Service isolation: the system is divided into several service modules according to certain principles. Each module is relatively independent without strong dependence.
-
Fusing degradation: when the downstream service slows down or fails due to excessive access pressure, the upstream service can temporarily cut off the call of the downstream service in order to protect the availability of the system.
-
Service flow restriction: flow restriction can be considered as a kind of service degradation. Flow restriction is to limit the input and output flow of the system to achieve the purpose of protecting the system. Such as postponement, rejection and partial rejection.
Hystrix
1. Introduction
It is a delay and fault-tolerant library open-source by Netfix, which is used to isolate access to remote systems, services or third-party libraries to prevent cascading failures, so as to improve system availability and fault tolerance.
2. Delay and fault tolerance
Package request, trip mechanism, resource isolation, monitoring, fallback mechanism, self repair
3. Introduce the Hystrix dependency (it has been inherited in feign)
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netfix-hystrix </artifactId> </dependency>
4. Configure to enable Hystrix
feign: hystrix: enabled: true
5. Customize an interface degradation logic
/** * Created with IntelliJ IDEA * User: GHYANG * Date: 2020-06-13 * Description: */ @Component public class ProductFeignClientCallBack implements PeoductFeignClient{ /** * Fuse degradation method * @param id * @return */ @Override public Product findById(Long id) { System.out.println("feign Call trigger fuse degradation method"); return null; } }
6. Add degradation method support to the interface
@FeignClient(name = "service-product",fallback = ProductFeignClientCallBack.class)
7. Configure timeout
hystrix: command: default: execution: isolation: thread: timeoutInmilliseconds: 3000 #The default connection timeout is 1s. If no data is returned in 1s, the degradation logic will be triggered automatically
8. Use the monitoring function
<!--introduce hystrix Monitoring dependency of--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netfix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netfix-hystrix-dashboard</artifactId> </dependency>
#1 -- expose the endpoints monitored by all actors management: endpoints: web: exposure: include: '*' #2 -- visit localhost: port / actor on the page/ hystrix.stream #3 -- activate the web monitoring platform @ EnableHystrixDashboard on the startup class
Alibaba Sentinel
- Rich application scenarios, complete real-time monitoring, extensive open source ecology, and perfect SPI extension points
1. Management console
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar xxxxxx.jar #localhost:8080 sentiel--sentiel
2. Give the service to the console management
<!--Parent project introduction Alibaba Realized SpringCloud--> <dependency> <grupId>com.alibaba.cloud</grupId> <artifactId>spring-cloud-alibaba-dependecies</artifactId> <version>2.1.0.RELEASE</ version> <type>pom</type> <scope>pom</scope> </dependency> <!--Sub project introduction sentinel--> <dependency> <grupId>com.alibaba.cloud</grupId> <artifactId>spring-cloud-starter-sentinel</artifactId> </dependency>
spring: cloud: sentinel: transport: dashboard: localhost:8080 #The request address of the sentinel console
3. Define degradation logic
/** * blockHandler:Declare the downgrade method called when the fuse is blown * fallback:Declare the degradation method to be executed when the exception is executed * value:Custom resource name (default is current full class name. Method name) * The specific fuse configuration needs to be configured in real time on the sentinel console */ @SentinelResource(blockHandler = "orderBlockHandler",fallback = "orderFallback")
4. Load local configuration
spring: cloud: sentinel: datasource: ds1: file: file: classpath: XXXX.json #Local xxx.json file data-type: json rule-type: flow
//Local json file configuration { { "resource":"orderFindById", "controlBahavior":0, "count":1, "grade":1, "limitApp":"default", "strategy":0 } }
6, Service gateway
Zuul 1.0 gateway
1. Introduction
2. Build Zuul gateway server
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netfix-eureka-client</artifactId> </dependency>
3. Routing
##Method 1: route configuration -- direct configuration zuul: routes: ##Configure product service mapping product-service: XXX #Routing id, arbitrary path: /product-service/** #Map path url: http://127.0.0.1:9001 #The actual microservice url address corresponding to the mapping path
##Method 2: route configuration -- configure according to service #This method needs to cooperate with eureka registry configuration #Where serviceId is the service name registered in the registry zuul: routes: ##Configure product service mapping product-service: XXX #Routing id, arbitrary path: /product-service/** #Map path serviceId: service-product
##Method 3: route configuration -- if the route id is consistent with the corresponding microservice serviceId (this method is used with Eureka) zuul: routes: service-product: /product-service/**
##Method 4: route default configuration - if the current microservice name service product can directly use the default path / service product / * * (this method is used with Eureka)
4. Filter
//Custom filter -- Take authentication as an example @Component public class LoginFilter entends ZuulFilter{ /** * Define filter type * pre: Filters executed before forwarding to microservices -- mostly for authentication * routing: Filters executed when routing requests * post: Filter executed after executing microservice to get return value * error: Filter to execute when an exception is thrown throughout the stage */ public String filterType(){ return "pre"; } /** * Specify the filter execution order * The smaller the return value, the higher the execution order */ public int filterOrder(){ return 1; } /** * Whether the current filter is effective*/ public boolean showFilter(){ return true; } //Execute business logic in filter /** * Case identification: * 1-All requests need to carry a parameter: access token * 2-Get request request * 3-Obtain the parameter access token through request * 4-Judge whether the token is empty */ public Object run() throws ZuulException{ System.out.println("Run Filter"); //1 - get the context object RequestContext provided by zuul RequestContext ctx = RequestContext.getCurrentContext(); //2 - get request from RequestContext HttpServletRequest request = ctx.getRequest(); //3-get the request parameter access token String token = request.getParameter("access-token"); //4-judgment if(token == null){ //Intercept request return authentication failed ctx.setSendZuulResponse(false);//Intercept request ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value()); } //If the token is not empty, return null to continue return null; } }
SpringCloud Gateway
1. Routing configuration
<!--springcloud Gateway Inside is through netty + webflux realization webflux Implementation and springmvc There is a conflict--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
#Method 1: direct configuration spring: cloud: gateway: routes: #Configure route: route id/url / assertion - id: product-service url: http://127.0.0.1:9001 #Target microservice request address predicates: -Path=/product/**
#Method 1: according to the microservice configuration spring: cloud: gateway: routes: #Configure route: route id/url / assertion - id: product-service url: lb://service-product #lb: / / pull the request path from the registry according to the microservice name predicates: -Path=/product/**
spring: cloud: gateway: routes: #Configure route: route id/url / assertion - id: product-service url: lb://service-product #lb: / / pull the request path from the registry according to the microservice name predicates: -Path=/product/** filters: - RewritePath=/product-service/(?<segment>.*),/$\{segment} #Path rewriting filter, the $character needs to be escaped in yaml discovery: locator: enabled: true #Turn on auto forwarding by service name lower-case-service-id: true #The microservice name is presented in lowercase
2. Filter
/** * Created with IntelliJ IDEA * User: GHYANG * Date: 2020-06-14 * Description:Customize a global filter to implement the GlobalFilter ordered interface */ @Component public class LoginFilter implements GlobalFilter, Ordered { /** * Specifies the execution order of the filter. The smaller the return value, the higher the execution priority * @return */ @Override public int getOrder() { return 0; } /** * Execute business logic in filter * @param exchange * @param chain * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("Custom global filter executed"); //Filter chain next return chain.filter(exchange); } }
3. Unified authentication
/** * Execute business logic in filter * Judge the access token of the request parameter * If this parameter exists: it means that the authentication is successful * If this parameter does not exist: authentication failed * ServerWebExchange: Equivalent to request and corresponding context (similar to RequestContext in zuul) * @param exchange * @param chain * @return */ @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { System.out.println("Custom global filter executed"); //Get request parameters String token = exchange.getRequest().getQueryParams().getFirst("access-token"); //judge if(token == null){ System.out.println("Fail"); exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); return exchange.getResponse().setComplete(); //Intercept request } //Filter chain next return chain.filter(exchange); }
4. Gateway current limiting
<!--Monitoring dependency--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--redis rely on--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>
spring: redis: host: localhost pool: 6379 database: 0 cloud: gateway: routes: #Configure route: route id/url / assertion - id: product-service url: lb://service-product #lb: / / pull the request path from the registry according to the microservice name predicates: -Path=/product-service/** filters: - name: RequestRateLimiter args: #Get objects from containers using spiel key-resolver: '#{@pathKeyResolver}' #Average rate of token bucket population per second redis-rate-limiter.replenishRate: 1 #Upper limit of token bucket redis-rate-limiter.bursCamacity: 3 - RewritePath=/product-service/(?<segment>.*),/$\{segment} #RequestRateLimiter: use the current limiting filter provided by spring cloud gateway #Parameter replenisrate: rate of population into token bucket #Parameter burstCapacity: capacity in token
@Configuration public class KeyResolverConfiguration { /** * Write flow restriction rules based on request path * The method name is the same as the key resolver in the configuration file: '{@ pathkeyresolver}' */ @Bean public KeyResolver pathKeyResolver() { //Customized KeyResolver return new KeyResolver() { /** * ServerWebExchange : * Context parameters */ public Mono<String> resolve(ServerWebExchange exchange) { return Mono.just( exchange.getRequest().getPath().toString()); } }; } /** * Current limiting based on request parameters * Request ABC? Userid = 1 * The method name is the same as the key resolver in the configuration file: '{@ pathkeyresolver}' */ @Bean public KeyResolver userKeyResolver() { return exchange -> Mono.just( exchange.getRequest().getQueryParams().getFirst("userId") //exchange.getRequest().getHeaders().getFirst("X-Forwarded-For") current limiting based on request ip ); } }
<!--sentinel Current limiting--> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-spring-cloud-gatewat-adapter</artifactId> </dependency>
/** * sentinel Current limiting configuration */ //@Configuration public class GatewayConfiguration { private final List<ViewResolver> viewResolvers; private final ServerCodecConfigurer serverCodecConfigurer; public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) { this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList); this.serverCodecConfigurer = serverCodecConfigurer; } /** * Configure the flow limiting exception handler: SentinelGatewayBlockExceptionHandler */ @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() { return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer); } /** * Configure flow limiting filter */ @Bean @Order(Ordered.HIGHEST_PRECEDENCE) public GlobalFilter sentinelGatewayFilter() { return new SentinelGatewayFilter(); } /** * Configure initialized current limiting parameters * Flow restriction rules for specifying resources * 1.Resource name (routing ID) - Product Service * 2.Configure statistics time -- setIntervalSec * 3.Configure current limit threshold -- setCount */ @PostConstruct public void initGatewayRules() { Set<GatewayFlowRule> rules = new HashSet<>(); // rules.add(new GatewayFlowRule("product-service") // .setCount(1) // .setIntervalSec(1) // ); rules.add(new GatewayFlowRule("product_api") .setCount(1).setIntervalSec(1) ); GatewayRuleManager.loadRules(rules); } /** * Custom API current limiting group * 1.Define groups * 2.Configure current limit rules for groups */ @PostConstruct private void initCustomizedApis() { Set<ApiDefinition> definitions = new HashSet<>(); ApiDefinition api1 = new ApiDefinition("product_api") .setPredicateItems(new HashSet<ApiPredicateItem>() {{ add(new ApiPathPredicateItem().setPattern("/product-service/product/**"). //All URLs opened with / product service / product / setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX)); }}); ApiDefinition api2 = new ApiDefinition("order_api") .setPredicateItems(new HashSet<ApiPredicateItem>() {{ add(new ApiPathPredicateItem().setPattern("/order-service/order")); //perfect match/order-service/order url of }}); definitions.add(api1); definitions.add(api2); GatewayApiDefinitionManager.loadApiDefinitions(definitions); } /** * Custom current limiting processor * Processor executed when current limiting is triggered */ @PostConstruct public void initBlockHandlers() { BlockRequestHandler blockHandler = new BlockRequestHandler() { public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) { Map map = new HashMap(); map.put("code",001); map.put("message","sorry,Current limit"); return ServerResponse.status(HttpStatus.OK) .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(map)); } }; GatewayCallbackManager.setBlockHandler(blockHandler); } }
spring: cloud: gateway: routes: #Configure route: route id/url / assertion - id: product-service url: lb://service-product #lb: / / pull the request path from the registry according to the microservice name predicates: -Path=/product/** filters: - RewritePath=/product-service/(?<segment>.*),/$\{segment} #Path rewriting filter, the $character needs to be escaped in yaml discovery: locator: enabled: true #Turn on auto forwarding by service name lower-case-service-id: true #The microservice name is presented in lowercase
5. High availability of gateway
-
High availability HA is one of the factors that must be considered in the design of distributed system architecture. It usually means to reduce the time that the system cannot provide services through design.
-
Build gateway cluster with nginx
Nginx analog gateway
<!--stay nginx.conf Configure reverse proxy--> <!--Route to order service--> location /api-product{ proxy_pass http://127.0.0.1:9002; } <!--Routing to Commodity Services--> location /api-order{ proxy_pass http://127.0.0.1:9002; }
7, Link tracking
Sleuth
<!--sleuth Link tracking--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency>
logging: level: root: INFO org.springframework.web.servlet.DispatcherServlet: DEBUG org.springframework.cloud.sleuth: DEBUG
Zipkin
-
Zipkin is an open source project, which is dedicated to collecting service timing data to solve the delay problem of microservice architecture, including data collection, storage, search and presentation.
-
Usage:
-
-
download Zipkin.jar Package and open
-
localhost:9411/Zipkin/
-
<dependency> <groupId>org.srpingframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
-
spring: zipkin: base-url: http://127.0.0.1:9411/ #server's request address sender: type: web #The transmission mode of data has been sent to the server in the form of http sleuth: sampler: probability: 1 #Sampling ratio (1 for full sampling)
-
-
Data persistence
-
-
Zipkin database table officially provided
-
#Database mount java -jar xxxx.jar --STORAGE_TYPE:mysql --MYSQL_HOST:127.0.0.1 --MYSQL_TOP_PORT:3306 --MYSQL_USER:root --MYSQL_PASS=xxx --MYSQL_DB=zipkin
-
-
Using message oriented middleware to optimize
-
Asynchronous data collection using rabbitMQ
-
- Prepare rabbitMQ server
- Modify the zipkin client to send the message in the form of rabbit to the mq server
- Modify the zipkin server to pull messages from rabbit
8, Spring cloud stream
-
In the actual enterprise development, message middleware is one of the most important components. Message middleware is mainly used to solve application decoupling, asynchronous message, traffic cutting edge and other problems, to achieve high performance, high availability, high scalability and final consistency architecture. Different middleware has different implementation methods and internal structures. When the message middleware in the early stage of the project changes with the middleware in the later stage, spring cloud stream can provide a decoupling method.
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-bindeer-rabbit</artifactId> </dependency>
#Message producer configuration spring: cloud: stream: bindings: output: destination: itcast-default #Specify the destination to send the message to binders: #Binder configuration defaultRabbit: type: rabbit #rabbit Middleware #Message consumer configuration spring: cloud: stream: bindings: input: #The built-in channel for getting messages, and getting messages from itcast default destination: itcast-default binders: defaultRabbit: type: rabbit
9, Configuration center
SpringCloud config
-
Spring cloud config project is a configuration management solution for distributed system, which includes two parts: client and server. Server provides the storage of configuration files and provides the content of configuration files in the form of interface. Client obtains data through the interface and initializes its own application based on the data.
-
File naming rules:
-
- {application}-{profile}.yml
- {application}-{profile}.properties
- {application} is the application name profile, which refers to the development environment (used to distinguish development environment, test environment, production environment, etc.)
<!--Configuration center dependency--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!--Sub pull configuration services--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
server: port: 10000 #Service port spring: application: name: config-server #Specify service name cloud: config: server: git: uri: https://xxxxxxxx.git #git address
#You need to create a configuration center to create a xxx.yaml file spring: cloud: config: name: product #The application name needs to correspond to the first half of the configuration file name in git profile: dev #development environment label: master #Branches in git uri: http://localhost:10000 #Request address of config server #Turn on dynamic refresh request path endpoint managment: endpoints: web: exposure: include: refresh
-
When the number of microservices is large, the remote configuration needs to send update access to postman every time it changes, which will increase the workload. There are corresponding solutions in spring cloud. Spring cloud bus connects distributed nodes with lightweight message agents, which can easily build a message bus to cooperate with Spring CloudConfig realizes the dynamic update of microservice application configuration information.
Apollo
-
Apollo P is an open-source configuration management center, which can centralize the configuration of different environments and clusters of applications. After the configuration is modified, it can be pushed to the application end in real time, and has the characteristics of standard permissions, process governance, etc.
-
Construction route:
- Download apollo related jar package and sql file
- Extract the downloaded zip package in linux environment and change demo.sh Database connection information in
<!--Apollo Client dependency--> <dependency> <groupId>com.ctrip.framework.apollp</groupId> <artifactId>apollo-client</artifactId> </dependency>
apollo: bootstrap: #Open apllo enbaled: true meta: http://192.168.74.101:8080 app: id: test01 #Specify AppId of apollo configuration center
10, Message bus
-
Message bus: in the microservice architecture, a lightweight message broker is usually used to build a common message subject to connect each microservice instance. The messages it broadcasts will be monitored and consumed by all microservice instances in the registry, also known as message bus
Configuration center integrated message bus
<!--Message bus dependency--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-bus</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-stream-binder-rabbit</artifactId> </dependency>
#Configure message middleware rabbit rabbit: host: 127.0.0.1 port: 5672 username: guest passwort: guest
11, Supplement
bootstrap.yml : used to execute when the program is booted, and used to read the configuration information earlier. For example, you can use bootstrap.yml to configure application.yml Parameters used in application.yml : application specific configuration information, which can be used to configure common parameters to be used in subsequent modules Loading order: bootstrap.yml Prior to application.yml
The above are personal study notes. Some of them may not be precise or wrong. I am a pure white. Welcome to point out