回目录 《spring分布式微服务入门》

我们今天来梳理归纳一下java的开发框架,首先为什么需要框架?

  1. 节约成本

不可能所有东西都从零造起,成本太高,spring融合了市场上大部分的开源项目,可以直接‘免费’利用

  1. 安全考虑

当前网络环境复杂,攻击无处不在,成熟的框架已经被主流公司接受使用,很多坑已经被前人踩过,站在巨人的肩膀上是明智之选,不用交额外的智商税

  1. 业务发展

spring boot不只是框架,还是spring cloud的一部分,spring cloud是微服务架构的一套完整是有序框架集合, spring是建筑材料,spring boot是脚手架,spring cloud就是行业规范,采用行业规范的开发模式有利于IT更好的服务business和业务拓展

1. Overview

1.1 SOA?微服务?

我们常说用spring boot构建微服务,又说spring cloud构建微服务,他们到底是什么关系?

引用我在微服务架构一章中关于微服务的解释:

首先微服务是啥,微服务首先是一种架构思想, 首先最初的很多产品都是单体monolithic架构,所有的服务都紧紧耦合在一个解决方案中,难以扩展,只能通过加cpu加内存的方式扩展,举例一个电商平台, 刚开始所有功能都放在一个解决方案,比如托管在Apache的一个war或者托管在iis的一个.net mvc程序, 随着项目的发展,团队的壮大,单体会变得庞大而难以维护,我们需要将功能拆分开,比如商家系统、买家系统、管理后台系统等,面向业务或者叫服务切分,分而治之,这种粒度的就是SOA架构, 其显著缺点: 1.从技术的角度,其实业务的切分在技术层面上仍然会有大面积的重叠,因此如果业务切割的不好,形成各种依赖,有可能在修改时牵一发而动全身 2.从业务角度来说,由于是业务的切分,所以当需要发展新的业务时就需要重新构建一个完全新的服务,不利于基于业务创新和发现 所以引入微服务的概念,微服务进一步将服务自底向上或自上到下做更细的切分,最下面是基础系统服务(短信、邮件、存储、缓存、消息推送等),中间是共享服务(支付系统、订单系统、仓储系统等), 最上面则是业务层(零售系统、团购系统、采购系统),比如我们要加一个闪购业务也是很轻松的,不用从底到上再来一遍,只需要基于基础服务和共享服务做业务开发

1.2 SpringBoot SpringCloud

Rod Johnson创建的开源框架interface21是 Spring的前身,随着spring从小框架发展为大而全的企业级框架,spring对市面上主流的开源软件都有了对应的组件支持, 人们发现使用spring项目开发变得难用,往往需要引入很多配置,难以维护容易出错,spring因此冠名配置地狱;

Spring boot是基于spring抽象出来的开发框架,是快速开发的scaffold脚手架,spring boot丧心病狂的运用依赖注入DI的思想,配置文件可以auto config,用户只需要定义好需要的bean, spring boot的大容器会进行管理,丰富的starter让开发者可以集中精力在业务逻辑上而不是依赖的配置管理;

依赖注入的思想简单来说就比如小孩要从冰箱拿吃的,但是不应该自己拿,应该交由家长来处理,因为小孩可能会忘记关冰箱门,可能会打乱冰箱里面其他东西,总之小孩这个组件应该只关心自己的事情,不要做这些大人才能做好的事情, 所以从冰箱拿东西吃要交由家长处理,在spring boot中,小孩可以采用构造函数注入或者setter based如autowired方式来使用家长组件;

spring-cloud是一套完整的微服务解决方案,是一系列框架的有序集合,提供了分布式的各种解决方案: 服务开发(springBoot spring springMVC)、服务配置中心(SpringCloudConfig Chef)、服务发现(eureka zookeeper)、服务调用(rest rpc)、负载均衡(ribbon nginx)、服务熔断器、服务监控、服务部署(docker kubernetes)、消息队列(kafka rabbitmq)

所以可见一个个具体的微服务(这里说的微服务就是具体的一个个应用了)是用spring boot开发,spring cloud又提供了服务配置中心、服务注册发现等所谓微服务治理的解决方案

1.spring boot是一个快速开发框架,应该说是spring系列的集大成者。我们可以简单的把spring boot理解成是一个快速开发的脚手架。 2.微服务往往是指Spring Cloud,微服务是一个框架。 3.如果把基于微服务架构的软件比作是一个大厦,钢筋混凝土结构就是spring cloud,而砖头瓦块等就是spring boot。微服务的一个一个服务是用spring boot开发的,spring cloud提供服务注册与发现、负载均衡、API网管、熔断路由、配置中心等框架性服务,当然一个完整的微服务系统有很多其他的内容,例如服务拆分、监控、限流降级等等。

dubbo常常拿来跟spring cloud对比,实际目前已经不具有可比性了,Dubbo现在只是一款高性能的Java RPC框架,只能跟spring cloud集合中的服务调用部分REST RPC做对比

spring cloud alibaba是spring cloud的其中一个微服务解决方案

2. Spring Framework

https://docs.spring.io/spring/docs/current/spring-framework-reference/ Project generator https://start.spring.io/ https://www.tutorialspoint.com/spring/spring_quick_guide.htm https://docs.spring.io/spring/docs/5.1.6.RELEASE/spring-framework-reference/ (spring boot 2.1.4 depend on spring 5.1.6)

architecture

Beans

Spring uses the class name and converts the first letter to lowercase.

https://www.baeldung.com/spring-bean-names

Autowired

https://www.baeldung.com/spring-autowire

Spring AOP

refer to aop-spring aop

代理

动态代理 静态代理 cglib 通过使用proxy设计模式 远程调用看起来像本地调用 增强类 如mybatis,fastclassbyspringcglib

保存生成的动态代理类或者增强类
@EnableAsync
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
    	System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"C:\\Workspace\\debug");
        SpringApplication.run(Application.class, args);
    }

Spring MVC

spring mvc 处理流程源码解析

3.SpringBoot Framework

springboot原理解析在这里

While the Spring framework focuses on providing flexibility to you, Spring Boot aims to shorten the code length and provide you with the easiest way to develop a web application. With annotation configuration and default codes, Spring Boot shortens the time involved in developing an application. https://www.tutorialspoint.com/spring_boot/index.htm

https://spring.io/tools3/sts/all

guides: https://spring.io/guides#gs https://spring.io/guides/gs/spring-boot/ Starters samples code: https://docs.spring.io/spring-boot/docs/2.1.4.RELEASE/reference/htmlsingle/#using-boot-starter https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples Docs: https://docs.spring.io/spring-boot/docs/2.1.4.RELEASE/reference/htmlsingle/ Unit test: https://stackabuse.com/how-to-test-a-spring-boot-application/ https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html

Spring Boot中如何干掉过多的if else! https://mp.weixin.qq.com/s/Uf8KGTbNcuDtwIlpMJnaXg

Spring boot web default web server: Asp.net default is IIS Express, how about spring boot web? Tomcat vs. Jetty vs. Undertow: Comparison of Spring Boot Embedded Servlet Containers https://examples.javacodegeeks.com/enterprise-java/spring/tomcat-vs-jetty-vs-undertow-comparison-of-spring-boot-embedded-servlet-containers/

3.1 Plugins

** spring-boot-maven-plugin

<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>${spring-boot-maven-plugin.version}</version>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>

这个plugin很重要,其中的repackage是把java程序打包成为executable程序,否则就只是普通的jar包(纠正:实际测试即使没用这个plugin,pom parent继承了org.springframework.boot,一样可以生成可执行程序,原因见后面关于这个包的解释),不能直接执行,比如hello world,需要javac之后生成的class,用java *.class才能执行,而且如果java程序比较负责,依赖了外部的包,还要给出classpath或libpath,极其麻烦,maven本身就是包管理器,最基本的职责就是mvn package打成普通的jar包,然后mvn install到本地.m2 repository,然后mvn deploy到远程的repository,当需要运行的时候就是用前面提到的java命令执行,当然也可以直接用mvn执行,好处是mvn会自动去.m2下面找到依赖的包, mvn exec:java -Dexec.mainClass=”com.example.Main” -Dexec.args=”arg0 arg1”,可以看到mvn实际也就是调用java命令 首先使用这个plugin的情况下,正常的mvn clean package,生成XXX-0.0.1-SNAPSHOT.jar和XXX-0.0.1-SNAPSHOT.jar.origninal: 可以重命名一下orignial为jar,反编译对比下:

对比可以看到,普通的jar包里面的东西被再次包入了BOOT-INF,然后增加了一个org.springframework.boot.loader的启动包 执行方法: project里:mvn spring-boot:run 打成包后:java -server -jar XXXX.jar –spring.config.location=/config/

这里居然还有个比较傻逼的比较 https://www.baeldung.com/spring-boot-run-maven-vs-executable-jar 有点意思,还有人这么较真

然后我好奇测试了下mvn最原始的打包plugin,看打成一个fat jar会如何 无法运行,估计是缺少springboot的上下文,spring boot的程序自然真正的入口应该是spring boot那个loader,加了annotation的那个所谓的入口main实际只是为spring boot loader准备的入口;

** maven-enforcer-plugin 这个是用来检查依赖问题的 mvn enforcer:enforce

3.2 Dependencies

Parent org.springframework.boot https://www.baeldung.com/spring-boot-dependency-management-custom-parent

继承两种方式: 直接写在parent里面; 写在dependencymanagement里面

<dependencyManagement>
     <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.6.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

如果没有继承org.springframework.boot,如果有多个入口方法,在pom中指定:

<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<mainClass>com.lyhistory.rce.shiro.WebApp</mainClass>
				</configuration>
				<executions>
					<execution>
						<goals>
							<goal>repackage</goal>
						</goals>
					</execution>
				</executions>
			</plugin>

如果继承org.springframework.boot,如果有多个入口方法,就多一种方式,在pom中指定:

<parent>
   	 <groupId>org.springframework.boot</groupId>
   	 <artifactId>spring-boot-starter-parent</artifactId>
   	 <version>1.5.9.RELEASE</version>
   	 <relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
  <start-class>com.xx.xx</start-class>
</properties>

3.3 Integration

3.3.1 redis

@Autowired Private RedisTemplate redisTemplate; https://github.com/spring-projects/spring-boot/issues/7238

一文搞定 Spring Data Redis 详解及实战 https://cloud.tencent.com/developer/article/1349818 SpringBoot下Redis相关配置是如何被初始化的 https://my.oschina.net/u/3866531/blog/1858069

Which type of injection?? 深度解析SpringBoot2.x整合Spring-Data-Redis https://www.itcodemonkey.com/article/13627.html

3.3.2 Shiro

more

Thymeleaf https://www.baeldung.com/thymeleaf-in-spring-mvc

4. Spring Cloud

spring cloud定义了接口标准,然后各家各组件做了不同实现;

从总体上看:

静态找FastDFS集群(便宜)或cdn服务(贵); 动态则进入下面流量网关

LVS的virtual ip概念,大概是一个数据包发送给192.168.1.1这个服务器,但是负载均衡给了192.168.1.2这个服务器,按照TCP协议,参考我在network的讲解,2这个服务器应该拒绝这个包,因此才引入了VIP的概念;

​ 前面网关部分,假如业务网关有多个节点,流量网关的nginx可以通过访问注册中心获得业务网关列表,从而对业务网关进行负载均衡;然后业务网关访问注册中心可以获取对应的微服务;当然所有的业务网关和微服务都是注册到注册中心的; ​ ​ 企业消息总线springcloud bus,kafka

从厂家看:

全局外部流量入口:zuul 动态路由 Hystrix熔断降级 微服务内部负载均衡:feign https://blog.csdn.net/zhou920786312/article/details/84982290 feign和ribbon都属于客户端负载均衡(正向代理,当然这里意图并不是说要隐藏客户端,而是反而客户端通过使用feignClient,feiginclient调用微服务B[多个节点在注册中心注册为B服务],从而隐藏具体的调用过程,比如怎么动态选择哪个节点的B服务,通过什么协议等等),nginx属于服务端负载均衡(反向代理),nginx不易于剔除非健康节点;

spring cloud gateway 网关代替zuul+hystrix,既有路由又有熔断降级

nacos代替了spring boot的properties或者yml配置,并且可以用于dns注册和rpc服务的注册和服务发现;

Feign 默认采用http,用于微服务的数据共享,微服务可以像调用自己的服务一样调用其他微服务提供的服务,类似于dubbo等rpc框架(rpc+动态代理)

bpm-business process management比如工单流程等: activiti or flowable

Spring Cloud 万字总结,真不错! https://mp.weixin.qq.com/s/YGtKoKBE1jxFaEUpEFSaLg

Azure Spring Cloud workshop https://docs.microsoft.com/en-us/learn/modules/azure-spring-cloud-workshop/

https://github.com/macrozheng/mall https://github.com/zhangdaiscott/jeecg-boot

https://github.com/ZhongFuCheng3y/msc-Demo https://github.com/forezp/SpringCloudLearning https://github.com/zhoutaoo/SpringCloud

todo: Mvc Thymeleaf Realm

5. Versions Compatibility

5.1 Spring VS Spring Integration VS Spring Boot VS 3rd-party clients

5.2 Compatibility Troubleshooting

5.3 3rd-party&wrapper: kafka

Client & Sever

Client & Client Wrapper

5.4 3rd-party&wrapper: Redis

https://github.com/spring-projects/spring-data-redis/issues/2061

Client & Server

Client & Client Wrapper


ref 为什么说 Java 程序员到了必须掌握 Spring Boot 的时候? 聊一聊Spring中的代理 Spring Cloud spring boot 和微服务的关系? 重新理解微服务 架构设计漫步:从单体架构、SOA到微服务 Microservices