微服务入门 | 项目分割 | 远程调度Feign | 用户中心erueka 和 nacos

news2024/11/23 15:41:19


认识微服务

微服务架构演变:

单体架构:所有功能集中在一个项目中开发,打成一个包部署

分布式架构:就是各功能模块的代码不在同一个项目中写了,到时候修改其中一个过能的代码,对另一个功能完全没有任何影响(如果在一个项目中,修改这个功能的代码,就得将所有功能代码给重新编译)

服务治理

问题:
服务拆分力度
服务集群地址如何维护
服务之间如何实现远程 调用
服务健康状态如何感知

微服务

良好架构设计的分布式架构方案,微服务架构特征
单一职责:功能单一
面向服务:对外暴露接口(让其他服务调用)
自治:团队独立,技术独立,数据独立,部署独立
隔离降级:服务做好隔离,容器,降级,避免出现级联问题

维护服务节点信息 – 注册中心
微服务配置的修改 – 配置中心
用户访问的微服务 – 服务网关
微服务间调用报错 – 服务保护

微服务入门案例

微服务技术.png

服务拆分与远程调用

服务拆分

拆分原则

这里我总结了微服务拆分时的几个原则:

  • 不同微服务,不要重复开发相同业务
  • 微服务数据独立,不要访问其它微服务的数据库
  • 微服务可以将自己的业务暴露为接口,供其它微服务调用

入门案例

  1. 创建父项目
  • 导入依赖:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.zjh</groupId>
    <artifactId>cloud-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>cloud-demo</name>
    <description>cloud-demo</description>

    <!--父工程-->
    <packaging>pom</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <!--  springCloud  -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR10</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--  mysql驱动  -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
                <version>8.0.15</version>
            </dependency>

            <!-- mybatis -->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.5.5</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

注意:
这里的环境是jdk8(建议大家和我一样)

  1. 创建子项目user-service
  • 导入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.zjh</groupId>
        <artifactId>cloud-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.zjh</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service</name>
    <description>user-service</description>
    <properties>
        <java.version>8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  • 创建实体类,mapper,service,controller

image.png

  • 添加mybatis-plus包扫描配置
@SpringBootApplication
@MapperScan("com.zjh.userservice.mapper")
public class UserServiceApplication {

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

}
  • yml配置设置
server:
  port: 8089
spring:
  application:
    name: userservice
  datasource:
    url: jdbc:mysql://localhost:3306/cloud?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    username: root
    password: 888888
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  type-aliases-package: com.zjh.order.pojo
  1. 创建子项目order-service

和user-service一模一样,唯一的区别是,需要再order-service中添加user-service的依赖

<dependency>
    <groupId>com.zjh</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

远程调度

远程调用就是在代码中访问到另一个项目的地址,这样就可以通过url来使用对方的方法,从而得到对方的信息
我们这里order中查询中的user属性直接查询时得不到的,需要通过访问user的信息,通过user-service中的getById()来得到,所以我们远程调度user-service项目

步骤:

  1. 在OrderServiceApplication中将RestTemplate添加到bean
@SpringBootApplication
@MapperScan("com.hwadee.order.mapper")
public class OrderServiceApplication {

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

	@Bean
	public RestTemplate restTemplate() {
		return new RestTemplate();
	}
}
  1. 调用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.利用RestTemplate发起http请求,查询用户
        // 2.1.url路径
        String url = "http://localhost:8081/user/" + order.getUserId();
        // 2.2.发送http请求,实现远程调用
        User user = restTemplate.getForObject(url, User.class);
        
        // 3.封装user到Order
        order.setUser(user);
        
        // 4.返回
        return order;
    }
}

支持请求:get,post,

存在问题:

  • order-service在发起远程调用的时候,该如何得知user-service实例的ip地址和端口?
  • 有多个user-service实例地址,order-service调用时该如何选择?
  • order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?

我们接下来就使用用户中心来看一看这个问题

Eureka注册中心

介绍

eureka工作流程
eureka注册中心.png
调用者就是服务消费者,被调用的对象就是服务提供者。注册中心,就是我们将服务提供者的路径给存到注册中心中,当服务消费者每次调用对面的服务,就通过注册中心来访问对面的服务

使用步骤

创建注册中心项目

  1. 添加依赖spring-cloud-starter-netflix-eureka-server
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.hwadee</groupId>
        <artifactId>cloud-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>eureka-server</artifactId>

    <dependencies>
        <!--eureka服务端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  1. 编写eureka启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
  1. 编写服务配置文件
server:
  port: 10086
spring:
  application:
    name: eureka-server
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
  1. 启动服务

启动微服务,然后在浏览器访问:http://127.0.0.1:10086

注册服务

  1. 在user-service的pom文件中,引入下面的eureka-client依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.2.10.RELEASE</version>
</dependency>

  1. 修改服务配置文件,向eureka注册服务,并添加名字
server:
  port: 8081

spring:
  application: # 给服务起名字
    name: user-service
  datasource:
    url: jdbc:mysql://localhost:3306/hwadee?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    
# 向eureka注册服务
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  type-aliases-package: com.hadee.user.pojo

使用

  1. 在order-service的pom文件中,引入下面的eureka-client依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    <version>2.2.10.RELEASE</version>
</dependency>

  1. 修改服务配置文件,向eureka注册服务,并添加名字
  2. 添加@LoadBalanced注解
  • @LoadBalanced,进行轮循(将同一个名字的服务进行轮询访问)
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}
  1. 使用
public Order queryOrderById(Long orderId) {
    // 1.查询订单
    Order order = orderMapper.findById(orderId);
    // 2.利用RestTemplate发起http请求,查询用户
    // 2.1.url路径
    String url = "http://user-service/user/" + order.getUserId();
    // 2.2.发送http请求,实现远程调用
    User user = restTemplate.getForObject(url, User.class);
    // 3.封装user到Order
    order.setUser(user);
    // 4.返回
    return order;
}

Ribuu负载均衡

Nacos注册中心

nacos介绍和安装

  1. 安装
  2. 运行

打开安装的nacos文件夹,在bin文件上建立终端页,输入以下语句启动

sh startup.sh -m standalone
  1. 访问

nacos注册中心地址: http://127.0.0.1:8848/nacos/index.html#/login (账号密码都是nacos)
如果读取不到,可以尝试将nacos注册中心中的内容删除,然后重新运行项目

简单使用

  1. 引入依赖
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-alibaba-dependencies</artifactId>
  <version>2.2.5.RELEASE</version>
  <type>pom</type>
  <scope>import</scope>
</dependency>
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
  1. 添加配置(user和order的.xml都需要)
spring:
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848

Nacos配置管理

将配置放到nacos中

springboot启动加载配置文件顺序
bootstrap.yml
application.properties
application.yml

增加dev,创建开发环境

dev – namespace 开发环境
public – namespace 生产环境

远程调用OpenFeign

  1. 引入依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.2.10.RELEASE</version>
</dependency>
  1. 添加注解@EnableFeignClients
@SpringBootApplication
@MapperScan("com.zjh.orderservice.mapper")
@EnableFeignClients
public class OrderServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}
  1. 编写Feign的接口类
@FeignClient("user-service")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}
  1. 使用
public Order queryOrderById(Long orderId) {
    // 1.查询订单
    Order order = orderMapper.findById(orderId);
    
    // 2.设置用户
    // 2.1 查询用户
    User user = userClient.findById(order.getUserId());
    // 2.2 设置user
    order.setUser(user);
    
    // 3.返回
    return order;
}

和使用mapper类似,就是调用接口的方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1394304.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux网络之PXE高效批量装机、Kickstart全自动化安装

一. PXE网络装机简介和相关知识 1. 常见的三种系统安装方式和相关文件 ① 三种系统安装方式 u启动安装&#xff1a;在U盘中下载相关的安装系统及镜像文件&#xff0c;u盘插机安装 光驱安装&#xff1a;将带有所需系统的光盘放进电脑服务器中&#xff0c;按照官方引导装机 …

【数据结构】栈的远房亲戚——队列

队列的基本概念 前言一、队列的定义二、队列的重要术语三、队列的基本操作四、数据结构的三要素4.1 线性表的三要素4.2 栈的三要素4.3 队列的三要素 结语 前言 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在经过前面内容的介绍&#xff0c;…

LabVIEW交变配流泵性能测试系统

利用LabVIEW软件与高级硬件结合&#xff0c;开发交变配流泵性能测试系统。该系统不仅提高了测试精度&#xff0c;还优化了工业自动化流程&#xff0c;代表了液压系统测试技术的进步。 开发了一种高精度的测试系统&#xff0c;该系统能够综合评估交变配流泵的性能&#xff0c;包…

【计算机硬件】2、指令系统、存储系统和缓存

文章目录 指令系统计算机指令的组成计算机指令执行过程指令的寻址方式&#xff08;怎么样找到操作数&#xff1f;&#xff09;1、顺序寻址2、跳跃寻址 指令操作数的寻址方式&#xff08;怎么样找到操作数&#xff1f;&#xff09;1、立即寻址方式2、直接寻址方式3、间接寻址方式…

Nginx 基础使用

目录结构 进入Nginx的主目录我们可以看到这些文件夹 client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp其中这几个文件夹在刚安装后是没有的&#xff0c;主要用来存放运行过程中的临时文件 client_body_temp fastcgi_temp proxy_temp scg…

QT获取程序编译时间与当前时间的区别及应用场景

一.获取编译时间与当前时间的区别 1.编译日期时间&#xff1a;这个信息通常用于标识某个源代码文件或整个应用程序的编译时间&#xff0c;程序一旦编译出来不会再改变&#xff0c;通常用于记录或跟踪代码的版本和更改历史。 2.运行当前日期时间&#xff1a;这是指程序在运行时…

刷题总结1.18 下午 (堆)

关联数组”是一种具有特殊索引方式的数组。不仅可以通过整数来索引它&#xff0c;还可以使用字符串或者其他类型的值&#xff08;除了NULL&#xff09;来索引它。 关联数组和数组类似&#xff0c;由以名称作为键的字段和方法组成。 它包含标量数据&#xff0c;可用索引值来单独…

基于springboot+vue的免税商品优选购物商城系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目背景…

文本生成探索:方法、任务与测评

目录 前言1 文本生成简介2 文本生成任务2.1 data-to-text2.2 对话生成2.3 机器翻译2.4 诗歌生成2.5 风格转移2.6 故事生成2.7 总结生成 3 语言建模4 译码策略4.1 贪婪译码策略4.2 Beam Search decoding4.3 Sampling based decoding 5 控制文本生成5.1 在文本前面加prompt5.2 修…

Node+Express编写接口---服务端

开始&#xff1a; 个人兴趣爱好&#xff0c;欢迎大家多多指教&#xff01;(点击直达源码!) node_vue_admin: 第一个以node为后端,vue为前端的后台管理项目https://gitee.com/ah-ah-bao/node_vue_admin.git 第一步:安装 安装Node.js 点击直达Node.js (nodejs.org) 安装Navic…

旅游项目day03

1. 前端整合后端发短信接口 2. 注册功能 后端提供注册接口&#xff0c;接受前端传入的参数&#xff0c;创建新的用户对象&#xff0c;保存到数据库。 接口设计&#xff1a; 实现步骤&#xff1a; 手机号码唯一性校验&#xff08;后端一定要再次校验手机号唯一性&#xff09…

vue3使用vue-masonry插件实现瀑布流

《Vue插件》瀑布流插件vue-masonry的使用与踩坑记录 参数:item-selector transition-duration column-width origin-left origin-top gutter 前言: 之前其实有分享过一篇纯CSS实现瀑布流的方法: https://oliver.blog.csdn.net/article/details/126450691&#xff0c;但纯CSS实现…

金融行业翻译怎么样,哪个翻译公司比较靠谱?

众所周知&#xff0c;金融翻译是一项具有高难度挑战性的任务&#xff0c;它会涉及到错综复杂的层面和专业性。随着国际间金融贸易的交流日益密切&#xff0c;金融翻译的需求也如春潮般汹涌而至。那么&#xff0c;这个金融行业翻译究竟有何独特之处&#xff0c;北京哪个翻译公司…

精通Discord营销:多账号注册与管理,高效打造矩阵

Discord虽然是一个海外小众平台&#xff0c;但在Z世代群体来说却非常受欢迎。通常在游戏行业、年轻化的电商特定品类、软件等业务中&#xff0c;Discord的社群营销可以起到非常卓越的效果。但是&#xff0c;您必须学会管理不同的帐户&#xff0c;以构成矩阵打造社区&#xff0c…

1. 安装Git

01. 安装Git 最早Git是在Linux上开发的&#xff0c;很长一段时间内&#xff0c;Git也只能在Linux和Unix系统上跑。不过&#xff0c;慢慢地有人把它移植到了Windows上。现在&#xff0c;Git可以在Linux、Unix、Mac和Windows这几大平台上正常运行了。 要使用Git&#xff0c;第一…

flutter 五点一:MaterialApp Theme

ThemeData factory ThemeData({bool? applyElevationOverlayColor, //material2的darkTheme下 增加一个半透明遮罩 来凸显阴影效果 material3下无效 貌似没啥用NoDefaultCupertinoThemeData? cupertinoOverrideTheme, //ios组件样式 Iterable<ThemeExtension<dyn…

Elasticsearch:聊天机器人教程(一)

在本教程中&#xff0c;你将构建一个大型语言模型 (LLM) 聊天机器人&#xff0c;该机器人使用称为检索增强生成 (RAG) 的模式。 使用 RAG 构建的聊天机器人可以克服 ChatGPT 等通用会话模型所具有的一些限制。 特别是&#xff0c;他们能够讨论和回答以下问题&#xff1a; 你的…

IPhone、IPad、安卓手机、平板以及鸿蒙系统使用惠普无线打印教程

演示机型&#xff1a;惠普M281fdw&#xff0c;测试可行机型&#xff1a;惠普M277&#xff0c;惠普M452、惠普M283 点击右上角图标。 点击WI-FI Direct 开&#xff0c;(如果WI-FI Direct关闭&#xff0c;请打开&#xff01;) 记录打印机的wifi名称(SSID)和密码。 打开IPhone、I…

Altium Designer简介以及下载安装

阅读引言&#xff1a; Altium Designer的离线安装包在文章最后&#xff0c; 注意该软件只能用于个人的学习使用&#xff0c; 不能用于商业用途&#xff0c; 文章主题图片来自网络。 一、Altium Designer简介 Altium Designer是一款功能强大的电子设计自动化&#xff08;EDA&…

HBase学习六:LSM树算法

1、简介 HBase是基于LSM树架构实现的,天生适合写多读少的应用场景。 LSM树本质上和B+树一样,是一种磁盘数据的索引结构。但和B+树不同的是,LSM树的索引对写入请求更友好。因为无论是何种写入请求,LSM树都会将写入操作处理为一次顺序写,而HDFS擅长的正是顺序写(且HDFS不…