Open rainit2006 opened 4 years ago
2014年一位名为马丁.福勒的工程师提出微服务架构设计理念。 http://martinfowler.com/articles/microservices.html https://yq.aliyun.com/articles/38515
什么是组件?我们的定义是:一个组件就是一个可以被独立替换和升级的软件单元。
倾向围绕业务功能的组织来分割服务。这些服务实现商业领域的软件,包括用户界面,持久化存储,任何的外部协作。因此,团队是跨职能的(cross-functional),包含开发过程所要求的所有技能:用户体验(user-experience)、数据库(database)和项目管理(project management)。
提议团队应该负责产品的整个生命周期。Amazon 理念是“你构建,你运维(you build, you run it)”,要求开发团队对软件产品的整个生命周期负责。这要求开发者每天都关注他们的软件运行如何,增加更用户的联系,同时承担一些售后支持。
HTTP request-response with resource API's and lightweight messaging。 第二种做法是通过轻量级消息总线来发布消息。这种的通信协议非常的单一(单一到只负责消息路由),像RabbitMQ或者ZeroMQ这样的简单的实现。 The biggest issue in changing a monolith into microservices lies in changing the communication pattern. A naive conversion from in-memory method calls to RPC leads to chatty communications which don't perform well. Instead you need to replace the fine-grained communication with a coarser -grained approach.
Splitting the monolith's components out into services we have a choice when building each of them. You want to use Node.js to standup a simple reports page? Go for it. Teams building microservices prefer a different approach to standards too. Rather than use a set of defined standards written down somewhere on paper they prefer the idea of producing useful tools that other developers can use to solve similar problems to the ones they are facing.
Decentralization of data management presents in a number of different ways. At the most abstract level, it means that the conceptual model of the world will differ between systems. This is a common issue when integrating across a large enterprise, the sales view of a customer will differ from the support view.
A useful way of thinking about this is the Domain-Driven Design notion of Bounded Context. DDD divides a complex domain up into multiple bounded contexts and maps out the relationships between them. (DDD把复杂的领域拆分成不同上下文边界以及它们之间的关系。) This process is useful for both monolithic and microservice architectures, but there is a natural correlation between service and context boundaries that helps clarify, and as we describe in the section on business capabilities, reinforce the separations.(但是服务间存在着明显的关系,帮助我们对上下文边界进行区分,同时也像我们在业务功能中谈到的,强行拆分。)
Many of the products or systems being build with microservices are being built by teams with extensive experience of Continuous Delivery and it's precursor, Continuous Integration.
微服务应用把实时的监控放在应用的各个阶段中,检测构架元素(每秒数据库的接收的请求数)和业务相关的指标(把分钟接收的定单数)。监控系统可以提供一种早期故障告警系统,让开发团队跟进并调查。
微服务实践者,通常有不断改进设计的背景,他们把服务分解成进一步的工具。这些工具可以让应用开发者在不改变速度情况下,控制都他们的应用的需求变更。变更控制不意味首减少变更,而是使用适当的方式和工具,让它更加频繁,至少,很好让它变得可控。
不论如何,当你试图软件系统拆分成组件时,你将面临着如何拆分的问题。那么我们的决定拆分我们应用的原则是什么呢?首要的因素,组件可以被独立替换和更新的,这意味着我们寻找的关键在于,我们要想象着重写一个组件而不影响它们之前的协作关系。事实上,许多的微服务小组给它进一步的预期:服务应该能够报废的,而不是要长久的发展的。
通信方式: Dubbo采用的是RPC通信,Spring Cloud采用的是基于HTTP的REST方式。
微服务的核心要素在于服务的发现、注册、路由、熔断、降级、分布式配置。
https://www.youtube.com/watch?v=zE_3_9Z6_zE 万变不离其宗,微服务要解决的四个问题:
根本问题:网络是不可靠的
下一代微服务标准:service mesh。其解决方案:Istio
https://zhuanlan.zhihu.com/p/61901608 https://philcalcado.com/2017/08/03/pattern_service_mesh.html
服务注册与发现:Nacos
启动:sh startup.sh -m standalone
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
....
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.1.RELEASE</version> // This is must.
</dependency>
2020-02-02 00:55:32.050 WARN 94303 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jacksonObjectMapperBuilder' defined in class path resource [org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$JacksonObjectMapperBuilderConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.http.converter.json.Jackson2ObjectMapperBuilder]: Factory method 'jacksonObjectMapperBuilder' threw exception; nested exception is java.lang.NoSuchMethodError: 'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.visibility(com.fasterxml.jackson.annotation.PropertyAccessor, com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility)'
2020-02-02 00:55:32.057 INFO 94303 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-02-02 00:55:32.062 ERROR 94303 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location: org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration$StandardJackson2ObjectMapperBuilderCustomizer.configureVisibility(JacksonAutoConfiguration.java:264)
The following method did not exist:
'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.visibility(com.fasterxml.jackson.annotation.PropertyAccessor, com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility)'
The method's class, org.springframework.http.converter.json.Jackson2ObjectMapperBuilder, is available from the following locations:
jar:file:/Users/weideng/.m2/repository/org/springframework/spring-web/5.0.8.RELEASE/spring-web-5.0.8.RELEASE.jar!/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.class
It was loaded from the following location:
file:/Users/weideng/.m2/repository/org/springframework/spring-web/5.0.8.RELEASE/spring-web-5.0.8.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.http.converter.json.Jackson2ObjectMapperBuilder
解决:删除.m2/repository/org/springframework/spring-web/下的5.0.8RELEASE目录,重新让maven加载最新的版本,从而解决。
解决方法: 降到Nacos v1.0.0, SpringBoot降到v2.0.6. 问题发生时的pom.xml
SpringBoot是2.1.11或2.1.12. 需要降版本到v2.0.6
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>0.9.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
原因:在pom文件里没有加入spring-boot-starter-web依赖导致的。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
https://blog.csdn.net/dear_Alice_moon/article/details/78274538
解答:修改port号 In each spring boot application, add application.properties file in src/main/resources folder. To override the default 8080 port, you have to use server.port property in the application.properties file. Make sure you set different port in each of the application. For example, set server.port=8888 in one application and server.port=9999 in another application, so that app1 will run on 8888 port and app2 will run on 9999 port.
需要在pom里追加依赖:spring-boot-starter-actuator 并在application.properties里追加:management.endpoints.web.exposure.include=* 而且浏览器地址栏里输入: http://127.0.0.1:8080/actuator/nacos-discovery (无论nacos provider的app名字叫什么)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
pom.xml 例子 for Nacos provider demo。 Nacos用的是v1.0.0
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
</parent>
<groupId>com.spring.cloud.example.demo</groupId>
<artifactId>hello-spring-cloud-alibaba-nacos-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-cloud-alibaba-nacos-provider</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.SpringCloud.demo.NacosProviderApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
For consumer
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>hello-spring-cloud-alibaba-nacos-provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-cloud-alibaba-nacos-consumer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud Begin -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>0.2.1.RELEASE</version>
</dependency>
<!-- Spring Cloud End -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
千锋教育-李卫民 https://www.funtl.com/zh/guide/Spring-Cloud-Alibaba.html#%E6%A6%82%E8%BF%B0
Spring cloud alibaba版本说明 https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E