1. What is a micro-registry services
Registration Center: Service Management, the core is to have a service registry, the heartbeat mechanism dynamic maintenance.
Why?
Micro-machine applications and services more and more, the caller needs to know the network address of the interface, if the configuration file on the way to control the network address for the new dynamic machine maintenance caused a big problem.
Mainstream registry: Zookeeper, Eureka, Consul, ETCD and so on.
Service Provider Provider: time to start their own network information reported to the registry.
Consumer Services Consumer: start their own network when reporting information to the registry, pull the relevant information Provider's network.
2. Knowledge of distributed application of theoretical knowledge CAP
CAP theorem: refers in a distributed system, Consistency (consistency), Availability (availability), Partition Tolerance (partition fault tolerance), three can be obtained simultaneously.
Consistency (C): Back up all data in a distributed system, if the same value at the same time. (Data from all nodes at the same time exactly the same, the more nodes, the more time-consuming data synchronization)
Availability (A): After the load is too large, if the entire cluster can read and write requests in response to the client. (Service has been available, and is the normal response time)
Partition fault tolerance (P): partition tolerance, high availability is, a collapse of the node, does not affect other nodes. (100 nodes, hang a few, does not affect the service, the more the better machine)
CAP theory means that in a distributed storage system, can only achieve the above two points. And because the current network hardware there will be delays and packet loss problems, so we must partition tolerance need to achieve. So we can only make trade-offs between consistency and availability.
the reason:
CA case satisfied, because P can not be met: synchronous data (C) takes time, in response to (A) should be within the normal time, the number of machines it would be less, so P is not satisfied.
CP case satisfied, the reason can not be met A: synchronous data (C) the number of machines required also more time ,, (P), but the time needed synchronization data, then it is not the normal response time, so A is not satisfied.
AP satisfies case, because C can not be met: the number of machines are mostly (P), in response to (A) the normal time, the data can not be synchronized in time to the other nodes, C is not satisfied.
Select Registry:
Zookeeper: CP designed to ensure the consistency of the time, built the cluster, a node failure, leader election row will be carried out, or more than half of the node is unavailable, you can not provide services, availability can not be met.
Eureka: AP principle, master-slave node, a node linked to, other nodes can use the automatic switch, to the center.
in conclusion:
P distributed system, it must meet, can only choose one of the A and C. Not the best choice, the best choice is to architecture design based on business scenarios, if required consistency, then select Zookeeper, such as the financial industry; If you go to availability, the Eureka, such as the electricity supplier system.
Eureka schematics:
The official address of the Spring Cloud system: http://projects.spring.io/spring-cloud/
reference:
https://www.jianshu.com/p/d32ae141f680
https://blog.csdn.net/zjcjava/article/details/78608892
3. Use the IDEA service center set up Eureka Server-side and start
The official document: http://cloud.spring.io/spring-cloud-netflix/single/spring-cloud-netflix.html#spring-cloud-eureka-server
Step 1: Create Project
And create a common Spring Boot project is the same, only need to select the following figure shows the dependence
Step two: add annotations @EnableEurekaServer
@SpringBootApplication @EnableEurekaServer public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
The third step: to increase the allocation application.yml (in fact, you can use application.properties, but the official line use yml, here we copy the official website)
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
Step Four: Visit registry page
Use http: // localhost: 8761 / to access the registry page, the address in accordance with the configuration file, the next note here, in accordance with the profile of said access address is: http: // localhost: 8761 / eureka /
However, different versions may be different, I used version is Greenwich, it can not add / eureka / otherwise it will report a 404 error
Eureka 管理后台出现一串红色字体:EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
This is a warning that there are on-line services is low.
Close inspection methods: Eureka join the server configuration file
server: enable-self-preservation: false
Note: self-protection mode is disabled closed, is enabled by default true state
4. Create a Goods and Services registered with the registry
Step 1: Create a Spring Boot application, registration and found to be dependent increase in service
Step Two: Analog product information stored in memory
The third step: the development of product list interface Interface Product Details
Step Four: Join registry profile address
Server: Port: 8771 # designated registration center address Eureka: Client: serviceUrl: defaultzone: HTTP: // localhost: 8761 / Eureka / # service name the Spring: the Application: name: Product -service
We can start multiple instances with the current project, Tutorial: https://blog.csdn.net/zhou520yue520/article/details/81167841
After the start, we can log the next page to access the registry, see the following results:
Why just add a registry address, you can sign up?
Official website explains:. By having spring-cloud-starter-netflix-eureka-client on the classpath, your application automatically registers with the Eureka Server (That is, such Jar package on the classpath, can automatically identify)
5. Call mode between common services
RPC: Remote Procedure Call, like call the local service (method) the same call to the server service. It supports synchronous, asynchronous calls. Establishing a TCP connection between the client and the server, you can create one at a time, you can also link multiple calls reuse once. PRC small packets.
Rest: Http request, support for multiple protocols and functions. Facilitate the development of low cost. Http large packets. Similarly HttpClient, URLConnection.
6. Order service calls Goods obtain product information
Step 1: Create order_service project
Note: The caller need to introduce rely Ribbon
Step 2: Use Ribbon (similar HTTPClient, URLConnection)
Start class adds comment
@Bean @LoadBalanced public Residual Template rest template () { return new Rest Template (); }
The third step: single pseudo-interfaces development
Step four: call by name merchandise, Getting product details
Note: The red logo is above the goods and services spring.application.name
@Service public class ProductOrderServiceImpl implements ProductOrderService { @Autowired private RestTemplate restTemplate; @Override public ProductOrder save(int userId, int productId) { Object obj = restTemplate.getForObject("http://product-service/api/v1/product/find?id="+productId, Object.class); System.out.println(obj); ProductOrder productOrder = new ProductOrder(); productOrder.setCreateTime(new Date()); productOrder.setUserId(userId); productOrder.setTradeNo(UUID.randomUUID().toString()); return productOrder; } }
When we visited many times by request, we can see a different port number from the console, stated that this is returned from the application of different data ports
Controller of goods and services as follows:
@RestController @ RequestMapping ( "/ API / v1 / Product" ) public class ProductController { @Value ( "server.port $ {}" ) Private String Port; @Autowired Private ProductService productService; / ** * Get all the Product List * @ return * / @RequestMapping ( "List" ) public Object List () { return productService.listProduct (); } / ** * find listings according ID * @param ID * @return * / @RequestMapping("find") public Object findById(int id){ Product product = productService.findById(id); Product result = new Product(); BeanUtils.copyProperties(product,result); result.setName( result.getName() + " data from port="+port ); return result; } }
We can also be called by another way calling
//调用方式二 ServiceInstance instance = loadBalancer.choose("product-service"); String url = String.format("http://%s:%s/api/v1/product/find?id="+productId, instance.getHost(),instance.getPort()); RestTemplate restTemplate = new RestTemplate(); Object obj = restTemplate.getForObject(url, Object.class); //Map<String,Object> productMap = restTemplate.getForObject(url, Map.class);
Call principle:
1) First, get a list from the registry Provider
2) by selecting a certain strategy wherein a node
3) back to the calling restTemplate
We can also customize load balancing strategy, the official website Description: http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#_customizing_the_ribbon_client_by_setting_properties
Server:
Port: 8781
# designated registration center address
Eureka:
Client:
serviceUrl:
defaultzone: HTTP: // localhost: 8761 / Eureka /
# service name
the Spring:
the Application:
name: the Order-Service # custom load balancing strategy
product-service :
Ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
Strategies:
1) If each machine configuration is the same, it is recommended not to modify the policy (recommended)
2) If the strong part of the machine configuration, you can instead WeightedResponseTimeRule
7. Use Feign order service reform
Feign: pseudo-RPC client (or nature with http)
The official document: https://cloud.spring.io/spring-cloud-openfeign/
The first step: Add dependence
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
Step Two: Start class increase @EnableFeignClients
@SpringBootApplication @EnableFeignClients public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
The third step: adding an interface and using annotations @FeignClient (name = "product-service")
package com.jwen.order_service.service; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * 商品服务客户端 */ @FeignClient(name = "product-service") public interface ProductClient { @GetMapping("/api/v1/product/find") String findById(@RequestParam(value = "id") int id); }
important point:
1) service name, and Http methods must correspond
2) Use RequestBody, you should use @PostMapping
3) When a plurality of parameters by @RequestParam (value = "id") int id invoke
Step 4: Changing coded call
package com.jwen.order_service.service.impl; import com.fasterxml.jackson.databind.JsonNode; import com.jwen.order_service.domain.ProductOrder; import com.jwen.order_service.service.ProductClient; import com.jwen.order_service.service.ProductOrderService; import com.jwen.order_service.utils.JsonUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; import java.util.UUID; @Service public class ProductOrderServiceImpl implements ProductOrderService { @Autowired private ProductClient productClient; @Override public ProductOrder save(int userId, int productId) { String response = productClient.findById(productId); JsonNode jsonNode = JsonUtils.str2JsonNode(response); ProductOrder productOrder = new ProductOrder(); productOrder.setCreateTime(new Date()); productOrder.setUserId(userId); productOrder.setTradeNo(UUID.randomUUID().toString()); productOrder.setProductName(jsonNode.get("name").toString()); productOrder.setPrice(Integer.parseInt(jsonNode.get("price").toString())); return productOrder; } }
Tools code JsonUtils
package com.jwen.order_service.utils; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; /** * json工具类 */ public class JsonUtils { private static final ObjectMapper objectMappper = new ObjectMapper(); /** * json字符串转JsonNode对象的方法 */ public static JsonNode str2JsonNode(String str){ try { return objectMappper.readTree(str); } catch (IOException e) { return null; } } }
Feign between Ribbon and two, should choose Feign. Feign default integrated Ribbon. To write more clear thinking and convenient. Annotations using configuration mode, configuration to facilitate fusing, etc.
Timeout Configuration
# Modify call timeout
Feign:
Client:
config:
default:
connectTimeout: 5000
ReadTimeout: 5000
Analog interface slow response thread to sleep for new ways
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }