随着互联网的发展以及业务的复杂度,单体应用越来越庞大,网站应用的规模不断扩大。我们在开发过程中,一个方法的代码不断增加,相同的代码肯定有的 ,我们都会进行拆分,达到可复用,需求的不断增加,同时也带来的是技术上的压力。系统架构因此也不断的演进、升级、迭代。从单一应用,到垂直拆分,到分布式服务,到SOA,以及现在火热的微服务架构,还有在Google带领下来势汹涌的Service Mesh服务网格
早期开发两三个人,以前的开发模式,SSH和SSM架构开发应用,将所有功能都部署在一起, 为了节约成本,部署见简单,用于简化增删改查工作量的数据访问框架(ORM)是影响项目开发的关键。
图片来源于网络
存在的问题:
优点:
当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆分:
优点:
缺点:
当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式调用是关键。
优点: -将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率 缺点: -系统间调用关系错综复杂,难以维护
当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键, 早期是阿里的Dubbo
以前出现了什么问题?
服务治理要做什么?
缺点:
前面说的SOA,英文翻译过来是面向服务。微服务,似乎也是服务,都是对系统进行拆分。因此两者非常容易混淆,但其实有一些差别:有效的拆分应用,实现敏捷开发和部署
微服务的特点:
1.一些列的独立的服务共同组成系统 2.单独部署,跑在自己的进程中 3.每个服务为独立的业务开发 4.分布式管理 5.非常强调隔离性
无论是微服务还是SOA,都面临着服务间的远程调用。那么服务间的远程调用方式有哪些呢? 常见的远程调用方式有以下几种:
RPC,即 Remote Procedure Call(远程过程调用),是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。说得通俗一点就是:A计算机提供一个服务,B计算机可以像调用本地服务那样调用A计算机的服务。 通过上面的概念,我们可以知道,实现RPC主要是做到两点:
要实现远程调用,肯定是通过网络传输数据。A程序提供服务,B程序通过网络将请求参数传递给A,A本地执行后得到结果,再
将结果返回给B程序。这里需要关注的有两点:
1.采用何种网络通讯协议? 现在比较流行的RPC框架,都会采用TCP作为底层传输协议
2.数据传输的格式怎样? 两个程序进行通讯,必须约定好数据传输格式。就好比两个人聊天,要用同一种语言,否则无法沟通。所以,我们必须定义好请求和响应的格式。另外,数据在网路中传输需要进行序列化,所以还需要约定统一的序列化的方式。
RPC调用流程图:
想要了解详细的RPC实现,给大家推荐一篇文章:自己动手实现RPC
rpc:远程过程调用,是一种协议,底层tcp。可以像调用本地方法一样调用远程方法 这里大家可以了解下Google的gRpc
Http协议:超文本传输协议,是一种应用层协议。规定了网络传输的请求格式、响应格式、资源定位和操作的方式等。但是底层采用什么网络传输协议,并没有规定,不过现在都是采用TCP协议作为底层传输协议。说到这里,大家可能觉得,Http与RPC的远程调用非常像,都是按照某种规定好的数据格式进行网络通信,有请求,有响应。没错,在这点来看,两者非常相似,但是还是有一些细微差别。
例如我们通过浏览器访问网站,就是通过Http协议。只不过浏览器把请求封装,发起请求以及接收响应,解析响应的事情都帮我们做了。如果是不通过浏览器,那么这些事情都需要自己去完成。
既然两种方式都可以实现远程调用,我们该如何选择呢?
因此,两者都有不同的使用场景:
那么我们该怎么选择呢?
微服务,更加强调的是独立、自治、灵活。而RPC方式的限制较多,因此微服务框架中,一般都会采用基于Http的Rest风格服务。
HttpClient是Apache公司的产品,是Http Components下的一个组件, 这里简单介绍下 发起get请求:
@Test public void testGet() throws IOException { HttpGet request = new HttpGet("http://www.baidu.com"); String response = this.httpClient.execute(request, new BasicResponseHandler()); System.out.println(response); }
发起Post请求:
@Testpublic void testPost() throws IOException { HttpPost request = new HttpPost("http://www.oschina.net/"); request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"); String response = this.httpClient.execute(request, new BasicResponseHandler()); System.out.println(response);}
假如自定义一个json返回值
@Testpublic void testGetPojo() throws IOException { HttpGet request = new HttpGet("http://localhost:8080/hello"); String response = this.httpClient.execute(request, new BasicResponseHandler()); System.out.println(response);}
我们实际得到的是一个json字符串:
{ "id": 1, "userName": "lihaodong", "age": 21, "sex": 2}
Spring提供了一个RestTemplate模板工具类,对基于Http的客户端进行了封装,并且实现了对象与json的序列化和反序列化,非常方便。RestTemplate并没有限定Http的客户端类型,而是进行了抽象,目前常用的3种都有支持:
@SpringBootApplicationpublic class HttpDemoApplication {
public static void main(String[] args) { SpringApplication.run(HttpDemoApplication.class, args); }
@Bean public RestTemplate restTemplate() { // 默认的RestTemplate,底层是走JDK的URLConnection方式。 return new RestTemplate(); }}
在测试类中直接@Autowired注入:
@RunWith(SpringRunner.class)@SpringBootTest(classes = HttpDemoApplication.class)public class HttpDemoApplicationTests {
@Autowired private RestTemplate restTemplate;
@Test public void httpGet() { User user = this.restTemplate.getForObject("http://localhost:8080/hello", String.class); System.out.println(user); }}
通过RestTemplate的getForObject()方法,传递url地址及对象的字节码,RestTemplate会自动发起请求,接收响应,如果是对象的话, 帮我们对响应结果进行反序列化
学习完了Http客户端工具,接下来就可以正式学习微服务了
微服务是一种架构方式,最终肯定需要技术架构去实施。
微服务的实现方式很多,但是最火的莫过于Spring Cloud了。为什么?
SpringCloud是Spring旗下的项目之一,官网地址:http://projects.spring.io/spring-cloud/
Spring最擅长的就是集成,把世界上最好的框架拿过来,集成到自己的项目中。
SpringCloud也是一样,它将现在非常流行的一些技术整合到一起,实现了诸如:配置管理,服务发现,智能路由,负载均衡,熔断器,控制总线,集群状态等等功能。其主要涉及的组件包括:
-Eureka:服务治理组件,包含服务注册中心,服务注册与发现机制的实现。(服务治理,服务注册/发现)
因为Spring Cloud不同其他独立项目,它拥有很多子项目的大项目。所以它是的版本是版本名+版本号 (如Angel.SR6)。 版本名:是伦敦的地铁名 版本号:SR(Service Releases)是固定的 ,大概意思是稳定版本。后面会有一个递增的数字。
SpringCloud的教程正式起航哈 下篇开始更