微服务
微服务是一种软件架构风格,它是以专注于单一职责的很多小型项目为基础,组合出复杂的大型应用。
微服务拆分
什么时候拆分?
-
• 创业型项目:先采用单体架构,快速开发,快速试错。随着规模扩大,逐渐拆分。
-
• 确定的大型项目:资金充足,目标明确,可以直接选择微服务架构,避免后续拆分的麻烦。
怎么拆分?
从拆分目标来说,要做到:
-
• 高内聚:每个微服务的职责要尽量单一,包含的业务相互关联度高、完整度高。
-
• 低耦合:每个微服务的功能要相对独立,尽量减少对其它微服务的依赖。
从拆分方式来说,一般包含两种方式:
-
• 纵向拆分:按照业务模块来拆分
-
• 横向拆分:抽取公共服务,提高复用性
黑马商城
以黑马商城为例,原来所有业务都在一个单体项目里,现在我们可以把他拆分为以下五个微服务
-
• 用户服务
-
• 商品服务
-
• 订单服务
-
• 购物车服务
-
• 支付服务
下面是拆分完毕的项目结构,这里因为测试了负载均衡,所以启动了两个商品微服务实例
注册中心
在微服务远程调用的过程中,包括两个角色:
-
• 服务提供者:提供接口供其它微服务访问,比如
item-service
-
• 服务消费者:调用其它微服务提供的接口,比如
cart-service
在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心
的概念
我们这里就采用了Nacos
(Alibaba公司出品,目前被集成在SpringCloudAlibaba中)
导入数据库
首先需要将nacos
所需要的sql
文件导入数据库(这里以mysql
为例)
配置数据库
然后创建一个配置文件在/root/nacos/custom.env
注意这里其实就是在配置nacos
的数据库
PREFER_HOST_MODE=hostname
MODE=standalone
SPRING_DATASOURCE_PLATFORM=mysql
MYSQL_SERVICE_HOST=192.168.88.188
MYSQL_SERVICE_DB_NAME=nacos
MYSQL_SERVICE_PORT=3306
MYSQL_SERVICE_USER=root
MYSQL_SERVICE_PASSWORD=123
MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
创建Nacos容器
使用docker
创建nacos
容器
docker run -d
--name nacos
--env-file ./nacos/custom.env
-p 8848:8848
-p 9848:9848
-p 9849:9849
--restart=always
nacos/nacos-server:v2.1.0-slim
启动完成后就可以访问nacos
登录页:http://IP:8848/nacos/
,账号密码都是nacos
服务注册
在application.yml
里添加nacos
配置
spring:
application:
name: item-service # 服务名称
cloud:
nacos:
server-addr: 192.168.88.188:8848 # nacos地址
访问控制台即可发现服务注册成功,可以看到服务实例信息
服务发现
在pom.xml里引入依赖,并在在application.yml
里添加nacos
配置
<!--nacos 服务注册发现-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
之后,服务调用者就可以利用负载均衡的算法,从多个实例中挑选一个去访问订阅服务。
常见的负载均衡算法有:
-
• 随机
-
• 轮询
-
• IP的hash
-
• 最近最少访问
-
• …
这里我们可以选择最简单的随机负载均衡。
OpenFeign远程调用
引入依赖
OpenFeign
可以让远程调用像本地方法调用一样简单
首先引入OpenFeign
的依赖和负载均衡的依赖
<!--openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--负载均衡器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
还有连接池的依赖,这里选用okhttp
<!--OK http 的依赖 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
在application.yml
里配置连接池生效
feign:
okhttp:
enabled: true # 开启OKHttp功能
启用组件
接下来,我们在项目启动类上添加注解,启动OpenFeign
功能:
@EnableFeignClients(basePackages = "top.zhengru.hmall.api.client", defaultConfiguration = DefaultFeignConfig.class)
@MapperScan("top.zhengru.hmall.pay.mapper")
@SpringBootApplication
public class PayApplication {
public static void main(String[] args) {
SpringApplication.run(PayApplication.class, args);
}
}
使用方法
一般来说,为了避免重复编写Client
接口(后面会提到),会采取两种方法来抽取代码(如图)
-
• 思路1:抽取到微服务之外的公共
module
-
• 思路2:每个微服务自己抽取一个
module
方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。
方案2抽取相对麻烦,工程结构相对更复杂,但服务之间耦合度降低。
我们这里采用了第二种方法,所以其他的服务可以通过依赖引入的方法来使用Client
<dependency>
<groupId>top.zhengru.hmall</groupId>
<artifactId>hm-api</artifactId>
<version>1.0.0</version>
</dependency>
接着可以看一下Client的写法
@FeignClient("item-service")
public interface ItemClient {
@GetMapping("/items")
List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
@PutMapping("/stock/deduct")
void deductStock(@RequestBody List<OrderDetailDTO> items);
}
在对应的service里,通过Client来远程调用
// private final IItemService itemService;
private final ItemClient itemClient;
// List<ItemDTO> items = itemService.queryItemByIds(itemIds);
List<ItemDTO> items = itemClient.queryItemByIds(itemIds);
配置日志级别
需要在开头启动类的注解@EnableFeignClients
里配置全局生效,想要局部生效也可以在某个Client
里配置
public class DefaultFeignConfig {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.FULL;
}
}
如果你觉得这篇文章对你有所帮助,记得走之前点个「赞」和「在看」哦
欢迎点击左下角「阅读原文」访问博客
原文始发于微信公众号(正如的集装箱):微服务框架(一):服务拆分和服务注册、远程调用
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/241858.html