优秀的编程知识分享平台

网站首页 > 技术文章 正文

Spring Cloud-初探微服务(spring cloud微服务架构实战派)

nanyue 2024-08-09 07:01:18 技术文章 9 ℃

在接触微服务之前首先梳理下以往项目的架构和一些相关技术点

传统服务架构

传统项目分为三层架构,将业务逻辑层、数据库访问层、控制层放入在一个项目中。

优点:适合于个人或者小团队开发,不适合大团队开发。

分布式项目架构

根据业务需求进行拆分成N个子系统,多个子系统相互协作才能完成业务流程子系统之间通讯,其中使用RPC等远程通讯技术。

相对于传统服务架构,分布式服务架构的优点:

1.拆分模块,利用接口通信,降低模块之间的耦合度。

2.将一个项目拆分成若干个子项目,不同的开发人员负责开发不同的子项目。

3.新增功能时只需要增加一个子项目,调用其它系统的接口就可以。

4.可以灵活的进行分布式部署。

当然有优点就有缺点:

1.系统之间交互需要使用远程通信,接口开发增加工作量。

2.各个模块有一些通用的业务逻辑无法共用。 为了解决分布式架构的缺点,引入了soa架构,SOA:Service Oriented Architecture面向服务的架构。 就是将工程拆分成服务层、表现层两个工程。服务层中包含业务逻辑,只需要对外提供服务即可。

表现层只需要处理和页面的交互,业务逻辑都是调用服务层的服务来实现。

项目集群

多台服务器部署相同应用构成一个集群

作用:通过负载均衡设备共同对外提供服务

RPC远程调用

RPC 的全称是 Remote Procedure Call 是一种进程间通信方式。

它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即无论是调用本地接口/服务的还是远程的接口/服务,本质上编写的调用代码基本相同。

比如两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数或者方法,由于不在一个内存空间,不能直接调用,这时候需要通过就可以应用RPC框架的实现来解决

restful

restful是一种架构设计风格,提供了设计原则和约束条件,而不是架构。而满足这些约束条件和原则的应用程序或设计就是 restful架构或服务。

soap

soap简单对象访问协议是一种数据交换协议规范, 是一种轻量的、简单的、基于XML的协议的规范。SOAP协议和HTTP协议一样,都是底层的通信协议,只是请求包的格式不同而已,SOAP包是XML格式的。soap基于xml并封装成了符合http协议,因此,它符合任何路由器、防火墙或代理服务器的要求。soap可以使用任何语言来完成,只要发送正确的soap请求即可,基于soap的服务可以在任何平台无需修改即可正常使用。

rpc

RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果。 RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯) RPC是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式) RPC在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。

rpc远程调用框架

1.RMI实现

利用java.rmi包实现,基于Java远程方法协议(Java Remote Method Protocol) 和java的原生序列化。

2.Hessian

是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能。基于HTTP协议,采用二进制编解码。

3.thrift

是一种可伸缩的跨语言服务的软件框架。thrift允许你定义一个描述文件,描述数据类型和服务接口。依据该文件,编译器方便地生成RPC客户端和服务器通信代码。

4.SpringCloud

为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。

5.Dubbo

是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和Spring框架无缝集成。

面型服务架构SOA

业务系统分解为多个组件,让每个组件都独立提供离散,自治,可复用的服务能力 通过服务的组合和编排来实现上层的业务流程

作用:简化维护,降低整体风险,伸缩灵活

1.微服务架构

1.1 什么是微服务架构

 了解了以上概念现在来介绍下什么是微服务架构,微服务架构设计理念是各服务之间相互隔离-分布式也是隔离,自治-分布式
 依赖整体组合、单一职责、边界、异步通信、独立部署等

 作用:各服务可独立应用,组合服务也可系统应用(巨石应用[monolith]的简化实现策略-平台思想)

1.2 SOA架构与微服务架构区别

 SOA架构主要针对企业级、采用ESB服务(ESB企业服务总线),非常重,需要序列化和反序列化,采用XML格式传输。
 微服务架构主要互联网公司,轻量级、小巧,独立运行,基于Http+Rest+JSON格式传输。

 ESB也可以说是传统中间件技术与XML、Web服务等技术相互结合的产物。

1.3 spring cloud

 SpringCloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、负载均衡、
 微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,可以在开发人员的电脑上跑。另外说明spring
 cloud是基于Springboot的,所以需要开发中对Springboot有一定的了解。

1.4 服务提供者与消费关系

 服务提供者:提供服务被人调用
 消费者:调用别人服务

1.5 spring cloud 解决了什么问题

 配置管理、服务发现(注册eureka、zookeeper)、服务注册、断路器、路由策略、负载均衡、全局锁、分布式会话、
 客户端调用、接口网关(ZUUL)、服务管理系统等

2.微服务简单模拟

2.1 首先构建一个maven项目

pom

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.ithzk.spring.cloud</groupId>
 <artifactId>SpringCloud_Demo</artifactId>
 <packaging>pom</packaging>
 <version>1.0-SNAPSHOT</version>
 <!--将当前项目申明为spring boot项目-->
 <parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>1.5.10.RELEASE</version>
 </parent>
 <modules>
 <module>consumer-order</module>
 <module>provider-user</module>
 </modules>

 <name>SpringCloud_Demo</name>
 <!-- FIXME change it to the project's website -->
 <url>http://www.example.com</url>

 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <maven.compiler.source>1.7</maven.compiler.source>
 <maven.compiler.target>1.7</maven.compiler.target>
 </properties>

 <dependencies>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>4.11</version>
 <scope>test</scope>
 </dependency>

 <dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-core</artifactId>
 <version>1.2.3</version>
 </dependency>
 <dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-classic</artifactId>
 <version>1.2.3</version>
 </dependency>
 </dependencies>

 <build>
 <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
 <plugins>
 <plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>
 <plugin>
 <artifactId>maven-clean-plugin</artifactId>
 <version>3.0.0</version>
 </plugin>
 <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
 <plugin>
 <artifactId>maven-resources-plugin</artifactId>
 <version>3.0.2</version>
 </plugin>
 <plugin>
 <artifactId>maven-compiler-plugin</artifactId>
 <version>3.7.0</version>
 </plugin>
 <plugin>
 <artifactId>maven-surefire-plugin</artifactId>
 <version>2.20.1</version>
 </plugin>
 <plugin>
 <artifactId>maven-jar-plugin</artifactId>
 <version>3.0.2</version>
 </plugin>
 <plugin>
 <artifactId>maven-install-plugin</artifactId>
 <version>2.5.2</version>
 </plugin>
 <plugin>
 <artifactId>maven-deploy-plugin</artifactId>
 <version>2.8.2</version>
 </plugin>
 </plugins>
 </pluginManagement>
 </build>
</project>
2.2 构建服务提供者子项目 provider-user

pom.xml

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 <version>1.4.7.RELEASE</version>
</dependency>

User.java

package com.ithzk.spring.cloud.entity;

/**
 * @author hzk
 * @date 2018/5/13
 */
public class User {

 private Integer id;

 private String name;

 private Integer age;

 public Integer getId() {
 return id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public Integer getAge() {
 return age;
 }

 public void setAge(Integer age) {
 this.age = age;
 }

 public User(Integer id, String name, Integer age) {
 this.id = id;
 this.name = name;
 this.age = age;
 }

 public User() {
 }
}

UserController.java

package com.ithzk.spring.cloud.controller;

import com.ithzk.spring.cloud.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author hzk
 * @date 2018/5/13
 */
@RestController("/")
public class UserController {

 @GetMapping("/user/{id}")
 public User getUser(@PathVariable Integer id){
 return new User(id,"zs",20);
 }
}

application.yml

server:
 port: 7900 #程序启动后的端口,也就是tomcat的端口,可自定义
spring:
 application:
 name: provider-user

UserApp.java

package com.ithzk.spring.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Hello world!
 *
 */
@SpringBootApplication
public class UserApp {

 public static void main(String[] args )
 {
 SpringApplication.run(UserApp.class);
 }
}

此时通过7900/user/xx可以访问接口获取json格式数据

2.3 构建服务消费者子项目 consumer-order

pom.xml

 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 <version>1.4.7.RELEASE</version>
 </dependency>

User.java

package com.ithzk.spring.cloud.entity;

/**
 * @author hzk
 * @date 2018/5/13
 */
public class User {

 private Integer id;

 private String name;

 private Integer age;

 public Integer getId() {
 return id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public Integer getAge() {
 return age;
 }

 public void setAge(Integer age) {
 this.age = age;
 }

 public User(Integer id, String name, Integer age) {
 this.id = id;
 this.name = name;
 this.age = age;
 }

 public User() {
 }
}

OrderController.java

package com.ithzk.spring.cloud.controller;

import com.ithzk.spring.cloud.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author hzk
 * @date 2018/5/13
 */
@RestController
public class OrderController {

 //spring 提供用于访问rest接口的模板对象
 @Autowired
 private RestTemplate restTemplate;

 @Value("${user.url}")
 private String url;

 @GetMapping("/order/{id}")
 public User getOrder(@PathVariable Integer id){
 //访问提供者 获取数据 通过rest访问获取的json数据转换为的User对象
 User user = restTemplate.getForObject(url + id, User.class);
 return user;
 }
}

application.yml

server:
 port: 8900
spring:
 application:
 name: consumer-order
user:
 url: http://localhost:7900/user/

Order.java

package com.ithzk.spring.cloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * Hello world!
 *
 */
@SpringBootApplication
public class OrderApp {

 //相当于xml中的bean标签 用于调用当前方法获取到指定的对象
 @Bean
 public RestTemplate getRestTemplate(){
 return new RestTemplate();
 }

 public static void main( String[] args )
 {
 SpringApplication.run(OrderApp.class);
 }
}

此时通过可以访问接口8900/order/x,接口转而请求7900/user/x获取json格式数据,这就是简单的微服务样例,之后博客中会开始进入spring-cloud的应用

最近发表
标签列表