提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
这是一篇初学者对springcloud的认识以及操作
一、springcloud是什么?
Spring cloud 是一系列框架的有序集合,是一种微服务架构,简化了分布式系统基础设施的开发,例如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等等。
优点:
1:开发简便,它整合的许多小组件都是轻量化组件
2:技术领先,springcloud整合的小组件都是较为领先的技术
缺点:
1:项目结构复杂,基本每一个组件都需要创建一个项目
2:部署门槛高,项目部署需要配合其他容器技术进行集群部署,学习成本高
说到微服务架构就会想到什么是架构
架构的演变顺序为
单体架构,水平扩展架构,垂直应用架构,分布式架构,微服务架构
在传统的小项目中往往把所有功能放在一个服务器中,这样会增加以后的维修和拓展成本,且一个服务器对高并发的请求效率过低,这个时候需要集群,分布式和负载平衡等等去解决
什么是集群:多台服务器干一个事情 (如所有人一起洗碗)
什么是分布式:多台服务器干不同的小事,所有小事组合成一个事情(如分工合作)
springcloud就是一种微服务架构(SOA)
在SOA框架中一般有三种角色 用快递软件为例子
1:注册中心 Eureka (简单理解为存放 服务提供方 和 服务消费方 信息的角色)
2:服务提供方 (例如-----查询人物信息功能 )
3:服务消费方 (例如-----查询快递信息功能)
以前查询快递信息功能和查询人物信息功能都存放在同一个服务器中、
人物信息和快递信息都存放在一个数据库中
当查询快递信息的同时,也可以成功查询到快递的主人信息
这样的坏处就是一旦出现问题则整个项目都无法使用,且单个服务器效率低下
由于分布式思想,现在把这两个功能放在两个不同的服务器中,及两个模块,建立两个数据库,一个是人物信息,一个是快递功能
当查询快递信息的同时,查询快递功能 则会向 查询人物信息功能 发送请求
发送请求方(查询快递)被称为-------服务消费方
接收请求 (查询人物) 被称为-------服务接收方
注意:只要你需要,服务消费方也可以作为服务接收方,且数量可以有多个,因为这只是一个概念
那么目前就会有一个问题,服务消费方如何找到服务提供方呢?
这个时候就需要注册中心来完成!
注册中心的目的就是 存放 服务提供方和服务消费方 信息的地方
也就是说开始前 要把 服务提供方和服务消费方 的信息注册到 注册中心
具体关系如图
这样当某一个区域出现问题维修起来效率就会提高且将来功能增多,用到负载平衡将大大提高项目效率
(后面的文章会一一讲解)
二、用springcloud来实现这些功能的步骤
1:创建maven工程
在idea中创建一个maven工程,并且在maven工程下创建三个maven子工程分别是Eureka-server,user-service,order-service (照应上文提到的springcloud的特点,每个小组件(Eureka)基本都有一个模块)
接着在父工程的pom.xml中导入依赖(由于springcloud于springboot的版本需要很强的对应,这里建议用jdk1.8,springboot版本2.3.9RELEASE)
代码如下(示例):
<!--版本管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
<mysql.version>5.1.47</mysql.version>
<mybatis.version>2.1.1</mybatis.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2:为user-service 和order-service模块完善,创建数据库
数据库设计 (主要是商品表内包含人物信息表的id字段,可以自行发挥创建)
人物信息表
物品信息表
(主要为简单的 mapper层,服务层,控制层,模型类,数据库的设计可以自己发挥,因人而异)
查询物品信息控制层方法
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("{orderId}")
public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
// 根据id查询订单并返回
return orderService.queryOrderById(orderId);
}
}
这样两个功能模块就写好了,但是还没有为他们注册任何信息,所以这是两个单独的功能模块
一个是查询物品信息
另一个是查询人物信息
2.为功能模块注册信息
注册信息一共有四步
一:搜先在Eureka模块的pom.xml导入依赖开启服务端,整个关系分为两部分
1:Eureka服务端 (注册中心)
2:Eureka客户端 (功能模块)
<dependencies>
<dependency>
<!-- eureka服务端 -->
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
二:为Eureka模块写一个springboot启动类,且加上注解@EnableEurekaServer说明开启服务
@SpringBootApplication
//注解开启eureka服务端
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class,args);
}
}
三:新建配置文件application.yml填写注册Eureka信息,Eureka也需要为自己注册信息,假设端口为10086
server:
port: 10086 # eureka服务端口
spring:
application:
name: eurekaserver # eureka服务名称
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
# 以上是服务信息,为自己注册服务,因为有可能有多个eureka集群
这样就完成了eureka模块的配置,可以通过idea的服务去启动eureka查看页面
这个即为为Eureka注册的信息
四:为客户端(服务模块)注册信息
以user-service为例子
1:导入客户端依赖
<!--eureka客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2:在application.yml中填写注册信息
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud-user?useSSL=false
username: root
password: 1234
driver-class-name: com.mysql.jdbc.Driver
application:
name: userservice # userservice服务名称
mybatis:
type-aliases-package: cn.itcast.user.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
由于是在spring下的配置,所以注意一下配置信息的段落
3:启动user-service模块且刷新Euraka网站即可发现user-service注册信息
同理,order-service的操作完全一样,这样就完成了客户端的注册
3.使服务消费者成功发送请求到服务提供者处
简单理解就是,查询 物品信息功能 在eurake注册中心发现了 人物信息功能 的ip于接口,准备查询人物信息。
具体步骤如下
一:在order-service的启动类中 注册RestTemplate
RestTemplate可以帮助我们发送请求到 服务提供方
/**
* 注册RestTemplate
*/
@Bean
//负载均衡
//@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
二:请求要在order-service模块的service层完成
package cn.itcast.order.service;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
//2.利用ResTemplate发起http请求
//由于未在eurake注册信息,所以跨模块请求只能通过ip加端口的方式请求,这样导致的后果是ip地址一旦改变则无法发送请求且频繁改变修改麻烦
//2.1:设置请求路径 (t'g)
//String url = "http://localhost:8081/user/"+order.getUserId();
//User user = restTemplate.getForObject(url, User.class);
//restTemplate下的方法有许多,可以根据想要发送的请求方式修改
//参数1为url,参数2为返回的类型
//当在Eureka注册中心完成注册只需要用注册名代替ip地址和端口既可以完成请求发送
//用注册名称代替硬编码
String url = "http://userservice/user/"+order.getUserId();
User user = restTemplate.getForObject(url, User.class);
//3:封装user
order.setUser(user);
// 4.返回
return order;
}
}
这样当查询物品的同时会自动查询人物信息,接着封装
4.当服务模块增多时,则需要用到负载均衡来提高效率
首先模拟一下集群效果(增加一个user-service模块来一起完成查询人物信息功能)
选择复制配置 Ctrl+D
在vm选项中填写-Dservice-port=8082,8082是为了不与本身的模块端口发生冲突
-D为属性,service-port为端口设置
点击应用和确定即可完成复制
将复制的功能模块启动则可以看到已经向Eureka发送注册信息
在order-service的服务层中添加注解开启负载均衡,它的默认方案是轮询(排好队一个一个服务器进行访问)
/**
* 注册RestTemplate
*/
@Bean
//负载均衡
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
完成以上步骤就已经完成了最基本的负载均衡了
当进行查询物品信息后,通过负载均衡会先访问人物信息模块8081端口,继续查询则会访问8082端口....
通过这样来解决同一时间多次请求效率低下的问题
可以通过清空控制台观看信息
接下来的文章将继续学习负载均衡Ribbon的知识
总结
以上是初学者对springcloud的一些认识