首页 > 编程语言 >微服务(Java分布式)详解

微服务(Java分布式)详解

时间:2024-03-03 18:45:34浏览次数:27  
标签:Java nacos springframework Nacos 详解 org import cloud 分布式

1. 概念

微服务是一种软件架构模式,它将应用程序分解为一组小型、自治的服务单元。
个人理解上:微服务就是将服务拆分,让一种服务在一台或者多台电脑上运行,如下图微服务技术栈所示:
image
注册中心可以配置在一台或者多台电脑上,将功能拆分,n台电脑共同实现一个软件

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

优点:

  1. 架构简单
  2. 部署成本低

缺点:耦合度高

微服务:一种良好的分布式架构方案

优点:拆分粒度更小、服务更独立、耦合度更低

缺点:架构非常复杂,运维、监控、部署难度提高

微服务技术对比:
image

2. 服务的远程调用

第一步:向spring容器中注入RestTemplate对象

在启动类(Application)中加入如下代码:

package cn.itcast.order;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
    // 注入
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

第二步:利用RestTemplate中getForObject方法或者postForObject方法发送请求

在业务逻辑层(一般是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);
        String url = "http://userservice/user/"+order.getUserId();
		// 4.调用,利用反序列化获取对象
        User user = restTemplate.getForObject(url, User.class);
        order.setUser(user);
        // 4.返回
        return order;
    }
}

3. 注册中心

Eureka

搭建Eureka服务器

1.创建Eureka服务器项目,引入spring-cloud-starter-netflix-eureka-server的依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

注:这里不用加版本号,因为在父工程的依赖中已经指定springboot、springcloud和springcloud依赖库(spring-cloud-dependencies)

2.编写启动类,添加@EnableEurekaServer注解

3.添加application.yml文件,编写下面的配置:

server:
	port:10086
spring:
	application:
		name: eurekaserver
eureka:
	client:
		service-url:
			defaultZone:http://127.0.0.1:10086/eureka/

Eureka自己也是服务,此处为注册自己

向Eureka服务器注册服务

在客户端项目中引入eureka-client依赖:

<!--eureka多户端放赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

在客户端项目的application.yml中配置eureka地址

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: 123
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice
eureka:
	client:
		service-url:#eureka的地址信息
			defaultZone: http://127.0.0.1:10086/eureka

消费者拉取所有生产者实现负载均衡(服务发现)

1.修改业务逻辑层(Service)的代码,修改访问的url路径,用服务名代替ip、端口:

String url ="http://userservice/user/"+ order.getUserId();

2.在消费者项目的启动类Application中的RestTemplate添加负载均衡注解:

package cn.itcast.order;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

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

    @Bean
    @LoadBalanced   //负载均衡注解
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

Ribbon负载均衡

原理:

image

策略:

image

默认为ZoneAvoidanceRule

通过定义IRule实现可以修改负载均衡规则,有两种方式:

1、代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:

@Bean
public IRule randomRule(){
return new RandomRule();
}

2、配置文件方式:在消费者的application.yml文件中,添加新的配置也可以修改规则:

userservice:#生产者服务名
  ribbon:
    NFLoadBalancerRuleclassName: com.alibaba.cloud.nacos.ribbon.NacosRule #负载均衡规则

特点:懒加载

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon :
	eager-load:
		enabled:true#开启饥饿加载
		clients:userservice#指定对userservice这个服务饥饿加载

Nacos

Nacos是阿里巴巴的产品,现在是Springcloud中的一个组件。相比Eureka功能更加丰富,在国内受欢迎程度较高。

安装

Windows安装:

开发阶段采用单机安装即可。

1.下载安装包
在Nacos的GitHub页面,提供有下载链接,可以下载编译好的Nacos服务端或者源代码:
GitHub主页:https://github.com/alibaba/nacos
GitHub的Release下载页:https://github.com/alibaba/nacos/releases

2.解压
将这个包解压到任意非中文目录下
目录说明:

  • bin:启动脚本
  • conf:配置文件

3.端口配置
Nacos的默认端口是8848,如果你电脑上的其它进程占用了8848端口,请先尝试关闭该进程。
如果无法关闭占用8848端口的进程,也可以进入nacos的conf目录,修改配置文件中的端口:
image

4.启动
启动非常简单,进入bin目录,结构如下:
然后执行命令即可:

  • windows命令:
    startup.cmd -m standalone
    

5.访问

在浏览器输入地址:http://127.0.0.1:8848/nacos即可:
默认的账号和密码都是nacos,进入后:

Linux安装:
Linux或者Mac安装方式与Windows类似。

1.安装JDK
Nacos依赖于JDK运行,索引Linux上也需要安装JDK才行。
上传jdk安装包
上传到某个目录,例如:/usr/local/
然后解压缩:

tar -xvf jdk-8u144-linux-x64.tar.gz

然后重命名为java
配置环境变量:

export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin

设置环境变量:

source /etc/profile

2.上传安装包

上传到Linux服务器的某个目录,例如/usr/local/src目录下:

3.解压
命令解压缩安装包:

tar -xvf nacos-server-1.4.1.tar.gz

然后删除安装包:

rm -rf nacos-server-1.4.1.tar.gz

4.端口配置
与windows中类似
5.启动
在nacos/bin目录中,输入命令启动Nacos:

sh startup.sh -m standalone

服务注册到nacos

1.在cloud-demo父工程中添加spring-cloud-alilbaba的管理依赖:
父工程:

<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>

如果存在Eureka依赖,注释掉原有的eureka依赖
2.添加nacos的客户端依赖:
客户端:

<!-- nacos客户端依赖包 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

Nacos服务分级存储模型

image

userservice功能——》区域集群(上海、杭州)——》每个区域下多个的实例(userservice代码)

配置文件中加入集群设置:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: 123
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: userservice
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: SH

cluster-name为集群名

NacosRule负载均衡(消费者调用生产者会优先调用同集群的生产者)

1、设置集群名称:

spring:
	cloud:
		nacos:
			server-addr:localhost:8848#nacos服务端地址
			discovery:
				cluster-name:Hz#配置集群名称,也就是机房位置

2、然后在消费者的yml文件中中设置负载均衡的IRule为NacosRule,这个规则优先会寻找与自己同集群的服务

userservice:
  ribbon:
    NFLoadBalancerRuleclassName: com.alibaba.cloud.nacos.ribbon.NacosRule# 负载均衡规则

3、注意将user-service的权重都设置为1,权重0-1,越大被访问的概率越大,权重设置为0则完全不会被访问(可以用来升级更新服务)

Nacos环境隔离

image

命名空间->分组->服务

  1. namespace用来做环境隔离
  2. 每个namespace都有唯-id
  3. 不同namespace下的服务不可见

实现:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: 123
    driver-class-name: com.mysql.jdbc.Driver
  application:
    name: orderservice
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ
        namespace: b5cf9721-b0f7-437c-90b6-8dff03e16254 #命名空间id

Nacos与Eureka区别

1.Nacos与eureka的共同点

都支持服务注册和服务拉取

都支持服务提供者心跳方式做健康检测

2.Nacos与Eureka的区别

Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式临时实例心跳不正常会被剔除,非临时实例则不会被剔除

Nacos支持服务列表变更的消息推送模式,服务列表更新更及时

Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式

Nacos配置管理

Nacos统一配置管理(先在Nacos中配置好配置文件)

image

image

微服务拉取上述Nacos配置

原理:

image

项目启动时会比读取application.yml更早读取bootstrap.yml文件,故而nacos配置文件的地址可以写在bootstrap.yml文件中

实现:

  1. 引入Nacos的配置管理客户端依赖:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

因为在子项目中不用写版本号,在父项目的pom文件的依赖库中已经定义

  1. 在需要配置服务的项目中的resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml:
spring:
  application:
    name: userservice
  profiles:
    active: dev
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        server-addr: localhost:8848 #配置文件的地址不写会找不到,报空指针错误
        file-extension: yaml

校验代码(Controller中获取nacos中的配置文件):

package cn.itcast.user.web;

import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Value("${pattern.dateformat}")
    private String dateformat;

    @GetMapping("/now")
    public String now(){
        System.out.println("================================="+dateformat);
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }

    /**
     * 路径: /user/110
     *
     * @param id 用户id
     * @return 用户
     */
    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id) {
        return userService.queryById(id);
    }
}

效果:image

输出nacos中配置的字符串,成功获取到

配置优先级:
image

Feign

远程调用

  1. 导包
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

  1. 启动类加注解@EnableFeignClients

  2. 写Client接口

import cn.itcast.order.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("userservice")
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}
  1. Service中自动注入,调用

标签:Java,nacos,springframework,Nacos,详解,org,import,cloud,分布式
From: https://www.cnblogs.com/beijie/p/18016622

相关文章

  • Java学习Day01
    开发语言汇总开发语言鼻祖,汇编语言C语言,面向过程的开发C++,是C语言的延伸,覆盖面向对象Java面向对象的开发,又叫C++--C#是Java的山寨Java发展史C语言的纯净版,无指针、内存的管理等C语言的纯净版,有如下特性:简单易用面向对象可移植性高性能分布式多线程安全性健壮......
  • 【Java基础】Maven入门笔记
    本篇笔记参考尚硅谷Maven课程,概括总结了Maven的核心功能Maven仓库地址:MavenRepository:Search/Browse/Explore一、Maven简介1.Maven是一个依赖管理工具、构建工具2.Maven介绍Maven是一款为Java项目管理构建、依赖管理的工具(软件),使用Maven可以自动化构建、测试、打......
  • PDF标准详解(二)——PDF 对象
    上一篇文章我们介绍了一个PDF文档应该包含的最基本的结构,并且手写了一个最简单的“HelloWorld”的PDF文档。后面我们介绍新的PDF标准给出示例时将以这个文档为基础,而不再给出完整的文档示例,小伙伴想自己测试可以根据上一节的文档来进行配置。对象上一节我们看到一个个奇奇怪......
  • Java笔记:Lambda表达式
    Lambda表达式在Java中是函数式编程的一种体现,允许把函数作为一个方法的参数传递进方法中,或者将函数作为方法的返回值。1.语法和基础使用语法://Lambda实现是一个简单的表达式(parameters)->expression;//Lambda实现是一个函数体(parameters)->{statements;}paramet......
  • java - 流式编程
    1.获取流的方法://1.从集合转化List<Integer>list=newArrayList<>();Stream<Integer>stream=list.stream();//转化为流stream.Collect(Collectors.toList());//转换为流,流再转回为集合。//2.自定义初始化Stream<Integer>stream=Stream.of(1,5,6,4,8,3,1,9); 2......
  • Java数组
    Java数组一、什么是数组数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。【数组下标从0开始】二、数组声明创建首先必须声明数组变量,才能在程......
  • Java学习笔记——第四天
    数组数组是什么数组就是一个容器,用来存一批同种类型的数据。数组有什么用遇到批量数据的存储和操作时,数组比变量更适合。代码简洁,逻辑清晰。数组的定义静态初始化数组定义数组的时候直接给数组赋值。格式1(完整格式)数据类型[]数组名=new数据类型[]{元素1,元素2,元素3…......
  • Java中类与类、类与接口、接口与接口之间是什么关系?
    Java中类与类之间是什么关系?1.依赖依赖是指一个类(称为依赖类)使用到了另一个类(称为被依赖类),而这种使用关系是具有偶然性的、临时性的、非常弱的,但是被依赖类(目标类)的变化会影响到依赖类。例如,比如人A要过河,需要借用一条船B,此时人A与船B之间的关系就是依赖。表现在代码层面,为类B......
  • Java方法
    何为方法Java方法是语句的集合,它们在一起执行一个功能,方法包含于类或对象中,方法在程序中被创建,在其他地方被引用设计方法的原则:保持方法的原子性-一个方法只完成1个功能,这样利于后期的拓展publicclassDemo01{publicstaticvoidmain(String[]args){ints......
  • 「java.util.concurrent并发包」之 Unsafe
    一unsafe介绍Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C......