Nacos

一:微服务

1.0:单体架构

MVC架构,分层开发,所有的功能都在一个系统里面

Nacos_第1张图片

优点:
1:部署简单: 由于是完整的结构体,可以直接部署在一个服务器上即可。
2:技术单一: 项目不需要复杂的技术栈,往往一套熟悉的技术栈就可以完成开发。
3:用人成本低: 单个程序员可以完成业务接口到数据库的整个流程。

缺点:
1:系统启动慢, 一个进程包含了所有的业务逻辑,涉及到的启动模块过多,导致系统的启动、重启时间周期过长;
2:系统错误隔离性差、可用性差,任何一个模块的错误均可能造成整个系统的宕机;
3:可伸缩性差:系统的扩容只能只对这个应用进行扩容,不能做到对某个功能点进行扩容;
4:线上问题修复周期长:任何一个线上问题修复需要对整个应用系统进行全面升级。
5. 跨语言程度差
6. 不利于安全管理,所有开发人员都拥有全量代码

结论:单体架构不适合互联网(访问量大、业务复杂)项目,只适合传统项目(政府、学校、外包)

1.1:微服务架构

译文:

微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相协作(通常是基于HTTP 协议的RESTfulAPI )。每个服务都围绕着具体业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应当尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建。

解读微服务特点:

1:微服务是一种项目架构思想(风格)

2:微服务架构是一系列小服务的组合

3:任何一个微服务,都是一个独立的进程

4:轻量级通信(跨语言,跨平台)

5:服务粒度(围绕业务功能拆分)

6:去中心化管理(不依赖某一种语言)

1.2:微服务架构的优势

1、是每个微服务组件都是简单灵活的,能够独立部署。不再像以前一样,应用需要一个庞大的应用服务器来支撑。

2、可以由一个小团队负责更专注专业,相应的也就更高效可靠。

3、微服务之间是松耦合的,微服务内部是高内聚的,每个微服务很容易按需扩展。

4、微服务架构与语言工具无关,自由选择合适的语言和工具,高效的完成业务目标即可。

1.3:微服务架构的缺点(挑战)

1、依赖服务变更很难跟踪,其他团队的服务接口文档过期怎么办,依赖的服务没有准备好,如何验证我开发的功能。

2、微服务放大了分布式架构的系列问题,如分布式事务怎么处理,依赖服务不稳定怎么办?

3、运维复杂度陡增,如:部署物数量多、监控进程多导致整体运维复杂度提升。

1.4:SpringCloud与微服务关系

  • springcloud为微服务思想提供了完美的解决方案

  • springcloud是一些列框架的集合体(微服务全家桶、服务的注册与发现、分布式事务、服务降级、服务熔断、服务限流。。。。)

    一般我们说springcloud 其实指的是 springcloud-netflix,springcloud并不是造轮子,只是把netflix公司的组件做二次开发

  • springcloud基于springboot实现

1.5:SpringBoot和SpringCloud关系

  • SpringBoot专注于快速方便的开发单个个体微服务。

  • SpringCloud是关注全局的微服务协调、整理、治理的框架,它将SpringBoot开发的单体整合并管理起来。

  • SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖关系。

二:服务注册与发现

2.0:相关概念

分布式服务:一个完整的功能,拆分给不同的服务去实现,每个服务完成特定的功能。

服务集群:一个服务可以部署多个服务实例(进程),形成一个服务集群

负载均衡:在集群的环境下,采用相应的负载均衡策略,平均化服务的负载问题

2.1:什么是服务注册与发现

服务注册:将服务注册到注册中心,注册中心维护服务的元数据信息

服务发现:服务的调用者,可以从注册中心根据应用名获取服务列表,客户端做负载均衡。

Nacos_第2张图片

2.2:注册中心对比

nacos:是阿里开源的,经过了阿里实践的

eureka:netflix公司的,现在不维护了,不开源了

Nacos_第3张图片

2.3:who is using

Nacos_第4张图片

三:nacos简介与安装

官网:https://nacos.io/zh-cn/docs/what-is-nacos.html

3.1:nacos功能与架构

nacos架构:

Nacos_第5张图片

nacos功能:

  • 名字服务 (Naming Service)

    命名服务是指通过指定的名字来获取资源或者服务的地址,提供者的信息
    

  • 配置服务 (Configuration Service)

    动态配置服务让您能够以中心化、外部化和动态化的方式管理所有环境的配置。动态配置消除了配置变更时重新部署应用和服务的需要。配置中心化管理让实现无状态服务更简单,也让按需弹性扩展服务更容易。
    

3.2:nacos安装

下载地址:https://github.com/alibaba/nacos/tags

  • 源码编译安装(不推荐)

    git clone https://github.com/alibaba/nacos.git
    cd nacos/
    mvn -Prelease-nacos -Dmaven.test.skip=true clean install -U  
    ls -al distribution/target/
    
    // change the $version to your actual path
    cd distribution/target/nacos-server-$version/nacos/bin
    
    
  • 解压安装(推荐)

第一步:解压

第二步:配置(conf>application.properties)


#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
spring.datasource.platform=mysql

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=123456

第三步:在mysql中创建nacos数据库

第四步:在nacos中建表(建表语句在conf>nacos-mysql.sql)

第五步:修改bin>startup.cmd

nacos-1.3.2之后默认使用的【集群方式】启动,需要手动改为standalone单机模式(编辑startup.cm文件)

Nacos_第6张图片

双击bin>startup.cmd,启动成功

3.3:nacos工作原理

四:微服务入门案例

4.1:boot与cloud版本

springboot:提供了快速开发微服务的能力
springcloud提供了微服务治理的能力(服务注册与发现、服务降级、限流、熔断、网关、负载均衡、配置中心...),为微服务开发提供了全家桶服务

springboot的版本查看地址:https://spring.io/projects/spring-boot#learn

springcloud的版本查看地址:https://spring.io/projects/spring-cloud#overview

详细版本对应信息查看:https://start.spring.io/actuator/info

Nacos_第7张图片

注意:
如果采用springboot和springcloud(springcloud netflix)那么使用以上版本对应就ok了,
但是如果要使用alibaba的组件(nacos、sentinel、RocketMQ、Seata)必须使用springcloud alibaba

4.2:SpringCloud-alibaba

Springcloud与springcloud-alibaba关系

◆ 我们通常说的SpringCloud,泛指Spring Cloud Netflix,也是springcloud第一代
◆ SpringCloud Alibaba是SpringCloud的子项目,是阿里巴巴结合自身微服务实践,
◆ SpringCloud Alibaba符合SpringCloud标准,依赖于springcloud

Nacos_第8张图片

4.3:确定版本

确定方式:通过查看springcloud alibaba 官网确定

https://github.com/alibaba/spring-cloud-alibaba/wiki/版本说明

Spring Cloud Version Spring Cloud Alibaba Version Spring Boot Version
Hoxton.SR8 2.2.3.RELEASE 2.3.2.RELEASE
Greenwich.SR6 2.1.3.RELEASE 2.1.13.RELEASE
Hoxton.SR8 2.2.2.RELEASE 2.3.2.RELEASE
Hoxton.SR3 2.2.1.RELEASE 2.2.5.RELEASE
Hoxton.RELEASE 2.2.0.RELEASE 2.2.X.RELEASE
Greenwich 2.1.2.RELEASE 2.1.X.RELEASE
Finchley 2.0.3.RELEASE 2.0.X.RELEASE
Edgware 1.5.1.RELEASE(停止维护,建议升级) 1.5.X.RELEASE

最终决定(版本号记忆):

springcloud-alibaba: 2.2.3.RELEASE

springcloud: Hoxton.SR8

springboot: 2.3.2.RELEASE

4.4:创建父工程

父工程锁定springboot、springcloud、springcloud-alibaba版本

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

    <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>com.alibaba.cloudgroupId>
                    <artifactId>spring-cloud-alibaba-dependenciesartifactId>
                    <version>2.2.3.RELEASEversion>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
                <dependency>
                    <groupId>org.springframework.cloudgroupId>
                    <artifactId>spring-cloud-dependenciesartifactId>
                    <version>Hoxton.SR8version>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
                <dependency>
                    <groupId>org.springframework.bootgroupId>
                    <artifactId>spring-boot-dependenciesartifactId>
                    <version>2.3.2.RELEASEversion>
                    <type>pomtype>
                    <scope>importscope>
                dependency>
            dependencies>
        dependencyManagement>

4.5:服务提供者(wfx-goods)

nacos学习文档:https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-discovery.adoc

4.5.1:pom.xml


<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">
    <parent>
        <artifactId>wfx-parentartifactId>
        <groupId>com.wfxgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>wfx-goodsartifactId>

    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>
        
        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
    dependencies>

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



project>

4.5.2:application.properties

server.port=8001
#微服务的服务名
spring.application.name=wfx-goods
#nacos server的地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#开启所有的端点监控
management.endpoints.web.exposure.include=*

4.5.3:启动类加注解

package com.wfx;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient//开启服务注册与发现
public class GoodsApplication {

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

}

4.5.4:查询商品接口

package com.wfx.web;

import com.wfx.goods.Goods;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/goods")
public class GoodsController {

    @GetMapping("findById")
    public Goods findById(String goodsId){

        return  new Goods(12,"华为meta10",1000);
    }

}

4.6:服务消费者

4.6.1:pom.xml


<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">
    <parent>
        <artifactId>wfx-parentartifactId>
        <groupId>com.wfxgroupId>
        <version>1.0-SNAPSHOTversion>
    parent>
    <modelVersion>4.0.0modelVersion>

    <artifactId>wfx-order-serviceartifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>

        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>


    dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
project>

4.6.2:application.properties

server.port=9001
spring.cloud.nacos.server-addr=127.0.0.1:8848
spring.application.name=wfx-order

4.6.3:启动类加注解

package com.wfx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * 

title: com.wfx

*

Company: wendao

* author zhuximing * date 2020/10/26 * description: */
@SpringBootApplication @EnableDiscoveryClient public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class,args); } //实例化 RestTemplate 实例 @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }

4.6.4:保存订单接口

package com.wfx.web;

import com.wfx.goods.Goods;
import com.wfx.order.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * 

title: com.wfx.web

*

Company: wendao

* author zhuximing * date 2020/10/26 * description: */
@RestController @RequestMapping("/order") public class OrderController { @Autowired private RestTemplate restTemplate; private String baseURL="http://wfx-goods:8001/"; @PostMapping("save") public Map save(@RequestBody Order order){ //1:获取商品信息(发送http请求) Goods goods = restTemplate.getForObject(baseURL + "goods/findById?goodsId=" + order.getGoodsId(), Goods.class); System.out.println(goods); //2:保存订单 System.out.println("保存订单成功"); return new HashMap(){{ put("msg","save order success"); put("code",200); }}; } }

4.6.5:nacos领域模型

当业务系统越来越繁杂的时候,微服务会越来越多,可以进行分namespace、group进行管理

不同的group的微服务是相互隔离的

不同的namespace的微服务是相互隔离的

Nacos_第9张图片

演示:服务发布的时候指定namespace和group

第一步:在nacos server控制台创建一个namespace

第二步:服务注册与发现,指定namespace和group

spring.cloud.nacos.discovery.namespace=3cadb64d-6b4c-4f84-b25f-ceb34c948951
spring.cloud.nacos.discovery.group=my-group

4.6.6:微服务集群演示

1:启动wfx-goods-service服务集群

#如果不指定端口,那么微服务启动时使用8001,如果指定端口,那么微服务就在指定端口启动
server.port=${port:8001}

8001
Nacos_第10张图片

8002

Nacos_第11张图片

2:演示负载均衡

默认就是轮询负载均衡

五:RestTemplate

5.1:什么是RestTemplate

1:RestTemplate是java模拟浏览器发送http请求的工具类
2:RestTemplate基于`Apache`的`HttpClient`实现。HttpClient使用起来太过繁琐。spring提供了一种简单便捷的模板类来进行操作,这就是`RestTemplate`。
RestTemplate了解即可,在开发环境不会用,开发使用OpenFeign

5.2:ForObject

get请求

Map goods = restTemplate.getForObject(BaseURL+"findGoodsById?goodsId=12", Map.class);
System.out.println(goods.get("goodsName"));

post请求(发送的是json串)

Map goods = restTemplate.postForObject(BaseURL + "/save", new Goods("huawei", 99.99), Map.class);
System.out.println(goods.get("code"));

提示:

1:微服务之间数据传输格式统一为json
2:entity的空构造方法要提供
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Goods  {

      private String goodsName;
      private double price;

}

5.3:ForEntity

get请求

ResponseEntity<Goods> forEntity = restTemplate.getForEntity(BaseURL + "findGoodsById?goodsId=12", Goods.class);

System.out.println("http status:"+forEntity.getStatusCode());
System.out.println("http response body:"+forEntity.getBody());

post请求

ResponseEntity<Map> responseEntity = restTemplate.postForEntity(BaseURL + "/save", new Goods("huawei", 99.99), Map.class);

System.out.println("http status:"+responseEntity.getStatusCode());
System.out.println("http response body:"+responseEntity.getBody());

六:负载均衡器Ribbon

6.1:Ribbon简介

Ribbon是Netflix公司开源的一个负载均衡的项目,是一个"客户端"负载均衡器,运行在客户端上

客户端负载均衡

Nacos_第12张图片

服务器端负载均衡

Nacos_第13张图片

6.2:Ribbon在项目中怎么使用

第一步:pom依赖

springcloud alibaba 对Ribbon做了兼容

Nacos_第14张图片

第二步:@LoadBalanced注解


@Bean
@LoadBalanced
public RestTemplate restTemplate(){

    return new RestTemplate();
}

6.3:Ribbon的工作流程

1:wfx-order-service,wfx-goods-service(2个实例),它们都会向注册中心注册服务

2:注册中心记录集群元数据信息,即应用名与ip:port映射

3:Ribbon拦截所有的请求,从请求信息中获取请求应用名

4:Ribbon根据应用名从nacos注册中心获取服务列表

5:ribbon从服务列表中通过相关均衡策略(Rules)获取具体某个实例

6:请求远程服务

6.4:Ribbon源码追踪

第一步:LB自动配置

LoadBalancerAutoConfiguration是Ribbon的自动配置类,在这个配置类里面配置了一个拦截器(LoadBalancerInterceptor),该拦截器会拦截所有请求,这就是Ribbon的入口

Nacos_第15张图片

第二步:LB拦截器

LoadBalancerInterceptor拦截所有的请求,获取应用名

Nacos_第16张图片

第三步:LB客户端(RibbonLoadBalancerClient)

LoadBalancerClient:接口

RibbonLoadBalancerClient:实现类

RibbonLoadBalancerClient.execute()

RibbonLoadBalancerClient.getServer(loadBalancer, hint)

DynamicServerListLoadBalancer.chooseServer(本类没有,父类有该方法)

ZoneAvoidanceRule.choose(本类没有,父类有该方法)

略名 策略声明 策略描述 实现说明
BestAvailableRule public class BestAvailableRule extends ClientConfigEnabledRoundRobinRule 选择一个最小的并发请求的server 逐个考察Server,如果Server被tripped了,则忽略,在选择其中ActiveRequestsCount最小的server
AvailabilityFilteringRule public class AvailabilityFilteringRule extends PredicateBasedRule 过滤掉那些因为一直连接失败的被标记为circuit tripped的后端server,并过滤掉那些高并发的的后端server(active connections 超过配置的阈值) 使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就就是检查status里记录的各个server的运行状态
WeightedResponseTimeRule public class WeightedResponseTimeRule extends RoundRobinRule 根据相应时间分配一个weight,x响应时间越长,weight越小,被选中的可能性越低。 一个后台线程定期的从status里面读取评价响应时间,为每个server计算一个weight。Weight的计算也比较简单responsetime 减去每个server自己平均的responsetime是server的权重。当刚开始运行,没有形成statas时,使用roubine策略选择server。
RetryRule public class RetryRule extends AbstractLoadBalancerRule 对选定的负载均衡策略机上重试机制。 在一个配置时间段内当选择server不成功,则一直尝试使用subRule的方式选择一个可用的server
RoundRobinRule public class RoundRobinRule extends AbstractLoadBalancerRule roundRobin方式轮询选择server 轮询index,选择index对应位置的server
RandomRule public class RandomRule extends AbstractLoadBalancerRule 随机选择一个server 在index上随机,选择index对应位置的server
ZoneAvoidanceRule(默认) public class ZoneAvoidanceRule extends PredicateBasedRule 复合判断server所在区域的性能和server的可用性选择server 使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。

6.5:切换Ribbon负载均衡策略

package com.wfx.rule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
//注意这个配置类必须放在@ComponentScan默认扫描的范围外
@Configuration
public class MyRule {

    @Bean
    public IRule getRule(){
        return  new RoundRobinRule();
    }

}

Nacos_第17张图片

6.6:解释为什么nacos关掉还能继续访问

问题:服务消费者一旦成功调用一次,nacos server关闭后还能继续访问?

答:当消费者第一次访问成功后,会将服务列表在本地做缓存,只要服务提供者不宕机(ip端口不变),那么能一直调用

​ 但是实际生产(服务提供者宕机、服务提供者会增加实例、服务提供者ip和端口会发生变化)

定时(30s)更新nacos client本地缓存的源码

DynamicServerListLoadBalancer.updateListOfServers
//从nacos server获取最新的实例列表
NacosServerList.getServers

七:nacos集群搭建

在实际生产环境中,必须保证Nacos高可用,否则一旦Nacos宕机,整个平台都会无法运行

7.1:nacos集群架构

Nacos_第18张图片

7.2:nacos集群搭建

1:nacos推荐搭建在linux服务器

2:伪集群,1台服务器搭建多个nacos实例,通过不同端口区分

3:真集群,nacos实例搭建在不同的服务器里面(生产推荐的)

7.2.1:集群规划

服务名 ip 端口 备注
nacos实例1 192.168.234.131 8848
nacos实例2 192.168.234.131 8858
nacos实例3 192.168.234.131 8868
nginx 192.168.234.131 80 反向代理nacos3个实例
mysql 192.168.234.131 3306 存储nacos数据

7.2.2:详细步骤

第一步:上传nacos包到linux服务器并解压

tar -zxvf nacos-server-1.3.2.tar.gz -C /export/server/

第二步:修改nacos连接数据库信息和服务ip

cd /export/server/nacos/conf/
vim application.properties
### Specify local server's IP:
nacos.inetutils.ip-address=192.168.234.131

### Count of DB:
db.num=1

### Connect URL of DB:
db.url.0=jdbc:mysql://192.168.234.131:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user=root
db.password=Admin123!

第三步:修改/export/server/nacos/bin/startup.sh 的JAVA_OPT

虚拟机内存调大到2G

原设置:
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
修改后:
JAVA_OPT="${JAVA_OPT} -server -Xms300m -Xmx300m -Xmn100m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=160m"

第四步:配置/export/server/nacos/conf/cluster.conf配置文件

修改集群配置文件的文件名

cp cluster.conf.example cluster.conf

192.168.234.122:8848
192.168.234.122:8858
192.168.234.122:8868

第五步:复制三份,同时修改监听端口

[root@zhuxm01 server]# cp nacos/   nacos8848 -r
[root@zhuxm01 server]# cp nacos/   nacos8858 -r
[root@zhuxm01 server]# cp nacos/   nacos8868 -r

第六步:分别启动nacos实例

创建nacos-cluster-startup.sh

sh /export/server/nacos8848/bin/startup.sh
sh /export/server/nacos8858/bin/startup.sh
sh /export/server/nacos8868/bin/startup.sh
echo "nacos-cluster-starting !!!!!"

第七步:修改服务(提供者、生产者)注册地址

建议使用springboot多环境切换

spring.cloud.nacos.discovery.server-addr=192.168.234.122:8848,192.168.234.122:8858,192.168.234.122:8868

第八步:配置nginx反向代理(可选)

upstream  nacos-cluster {
       server    192.168.234.122:8848;
       server    192.168.234.122:8858;
       server    192.168.234.122:8868;
     }

server {
        listen       80;
        server_name  www.nacos.com;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location / {
           proxy_pass http://nacos-cluster/;
        }
}

八:Spring Cloud OpenFeign

作为Spring Cloud的子项目之一,Spring Cloud OpenFeign 是一种声明式、模板化的 HTTP 客户端,在 Spring Cloud 中使用 OpenFeign,可以做到使用 HTTP请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是个 HTTP 请求。同时OpenFeign通过集成Ribbon实现客户端的负载均衡

8.1:演示案例说明

wfx-order为服务消费者

wfx-jifen为服务提供者

功能1:添加订单,生成一条积分记录

功能2:修改订单,修改积分记录

功能3:删除订单,删除积分记录

功能4:查询订单,获取积分记录

8.2:新建积分微服务

8.2.1:pom依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-actuatorartifactId>
        dependency>

        <dependency>
            <groupId>com.alibaba.cloudgroupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
        dependency>
    dependencies>

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

8.2.2:application.properties

server.port=8003
spring.application.name=wfx-jifen
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
management.endpoints.web.exposure.include=*

8.2.3:启动类

@SpringBootApplication
@EnableDiscoveryClient
public class JifenApplication {

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

}

8.2.4:暴露接口

package com.wfx.web;

import com.wfx.jifen.Jifen;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@RestController
@RequestMapping("/jifen")
public class JifenController {

    @PostMapping(value = "/save")
    public Map save(@RequestBody Jifen jifen) {

        System.out.println("调用了积分保存接口");
        System.out.println(jifen);
        return new HashMap(){{
            put("isSuccess",true);
            put("msg","save success");
        }};

    }
 
    @PostMapping(value = "/update")
    public Map update(@RequestBody Jifen jifen) {

        System.out.println(jifen);
        return new HashMap(){{
            put("isSuccess",true);
            put("msg","update success");
        }};
 
    }
 
 
 
    @GetMapping(value = "/delete")
    public Map deleteById(Integer jifenId) {
        System.out.println("删除id为"+jifenId+"的积分信息");
        return new HashMap(){{
            put("isSuccess",true);
            put("msg","delete success");
        }};

    }
 
 
 
 
    @GetMapping(value = "/{jifenId}")
    public Jifen findJifenById(@PathVariable Integer jifenId) {
        System.out.println("已经查询到"+jifenId+"积分数据");
        return new Jifen(jifenId, 12,jifenId+"号积分");
    }
 
 
    @GetMapping(value = "/search")
    public Jifen search(Integer uid,String type) {
        System.out.println("uid:"+uid+"type:"+type);
        return new Jifen(uid, 12,type);
    }
 
    @PostMapping(value = "/searchByEntity")
    public List<Jifen> searchMap(@RequestBody  Jifen jifen) {
 
        System.out.println(jifen);
 
        List<Jifen> jifens = new ArrayList<Jifen>();
        jifens.add(new Jifen(110,12,"下单积分"));
        jifens.add(new Jifen(111,18,"支付积分"));
        return  jifens;
    }
 
}

8.3:wfx-order集成openfeign

8.3.1:openfeign依赖

<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-openfeignartifactId>
dependency>

Nacos_第19张图片

8.3.2:接口声明-保存积分

http接口的声明

@Component
@FeignClient("wfx-jifen")
public interface IJifenBiz {
    @PostMapping(value = "/jifen/save")
    public Map save(@RequestBody Jifen jifen) ;
}

8.3.3:接口远程调用-保存积分

 @Autowired
    private IJifenBiz iJifenBiz;
    @PostMapping("save")
    public ResultVo save(@RequestBody Order order){

        //保存订单
        System.out.println("保存订单成功");
        //保存积分
        Jifen jifen = new Jifen(order.getUid(),12,"下单积分");
        iJifenBiz.save(jifen);
        return new ResultVo(true,"save success");
    }

8.3.4:postman测试

8.4.1:接口声明-修改积分

@PostMapping(value = "/jifen/update")
public Map update(@RequestBody Jifen jifen);

8.4.2:接口远程调用-修改积分

@PostMapping("update")
public ResultVo update(@RequestBody Order order){

    //修改订单
    System.out.println("修改订单成功");
    //修改积分
    Jifen jifen = new Jifen(order.getUid(),12,"修改积分");
    iJifenBiz.update(jifen);
    return new ResultVo(true,"save success");
}

8.4.3:postman测试

8.5.1:接口声明-删除积分

@GetMapping(value = "/jifen/delete")
public Map deleteById(@RequestParam("jifenId") String jifenid) ;

8.5.2:接口调用-删除积分

 @GetMapping("delete")
    public ResultVo delete(String orderNum){

        //删除订单
        System.out.println("删除订单成功");
        //删除订单的积分
        iJifenBiz.deleteById("188");
        return new ResultVo(true,"save success");
    }

8.5.3:post测试

8.6.1:接口声明-根据id获取积分

@GetMapping(value = "/jifen/{jifenId}")
public Jifen findJifenById(@PathVariable("jifenId") Integer jifenId);

8.6.2:接口调用-根据id获取积分

@GetMapping("findByOrderNum")
public ResultVo findByOrderNum(String orderNum){
    //获取订单
    System.out.println("获取订单");
    //获取订单的积分
    Jifen jifen = iJifenBiz.findJifenById(123);
    System.out.println("远程获取到积分信息"+jifen);
    return new ResultVo(true,"save success");
}

8.6.3:post测试

8.7.1:声明接口-查询积分

@GetMapping(value = "/jifen/search")
public Jifen search(@RequestParam("uid") Integer uid,@RequestParam("type") String type);

8.7.2:调用接口-查询积分

@GetMapping("findByOrderNum1")
public ResultVo findByOrderNum1(String orderNum){
    //获取订单
    System.out.println("获取订单");
    //获取订单的积分
    Jifen jifen = iJifenBiz.search(123,"关注获取积分");
    System.out.println("远程获取到积分信息"+jifen);
    return new ResultVo(true,"save success");
}

8.7.3:postman测试

8.8.1:声明接口-查询积分

@PostMapping(value = "/jifen/searchByEntity")
public List<Jifen> searchByEntity(@RequestBody  Jifen jifen);

8.8.2:调用接口-查询积分

@GetMapping("findByOrderNum2")
public ResultVo findByOrderNum2(String orderNum){
    //获取订单
    System.out.println("获取订单");
    //获取订单的积分
    List<Jifen> jifens = iJifenBiz.searchByEntity(new Jifen(88, 56, "下单积分"));

    for (Jifen jifen : jifens) {
        System.out.println("远程获取到积分信息"+jifen);
    }

    return new ResultVo(true,"save success");
}

8.7.4:postman测试

8.4:OpenFeign超时控制

Feign 的[负载均衡底层用的就是 Ribbon

在application.properties中添加如下配置,超过5秒没连接上报连接超时,如果超过5秒没有响应,报请求超时

#全局配置
# 请求连接的超时时间 默认的时间为 1 秒
ribbon.ConnectTimeout=5000
# 请求处理的超时时间  默认的时间为 1 秒
ribbon.ReadTimeout=5000

ln(“远程获取到积分信息”+jifen);
return new ResultVo(true,“save success”);
}




### 8.6.3:post测试





### 8.7.1:声明接口-查询积分

```java
@GetMapping(value = "/jifen/search")
public Jifen search(@RequestParam("uid") Integer uid,@RequestParam("type") String type);

8.7.2:调用接口-查询积分

@GetMapping("findByOrderNum1")
public ResultVo findByOrderNum1(String orderNum){
    //获取订单
    System.out.println("获取订单");
    //获取订单的积分
    Jifen jifen = iJifenBiz.search(123,"关注获取积分");
    System.out.println("远程获取到积分信息"+jifen);
    return new ResultVo(true,"save success");
}

8.7.3:postman测试

8.8.1:声明接口-查询积分

@PostMapping(value = "/jifen/searchByEntity")
public List<Jifen> searchByEntity(@RequestBody  Jifen jifen);

8.8.2:调用接口-查询积分

@GetMapping("findByOrderNum2")
public ResultVo findByOrderNum2(String orderNum){
    //获取订单
    System.out.println("获取订单");
    //获取订单的积分
    List<Jifen> jifens = iJifenBiz.searchByEntity(new Jifen(88, 56, "下单积分"));

    for (Jifen jifen : jifens) {
        System.out.println("远程获取到积分信息"+jifen);
    }

    return new ResultVo(true,"save success");
}

8.7.4:postman测试

8.4:OpenFeign超时控制

Feign 的[负载均衡底层用的就是 Ribbon

在application.properties中添加如下配置,超过5秒没连接上报连接超时,如果超过5秒没有响应,报请求超时

#全局配置
# 请求连接的超时时间 默认的时间为 1 秒
ribbon.ConnectTimeout=5000
# 请求处理的超时时间  默认的时间为 1 秒
ribbon.ReadTimeout=5000

总结:

  1. Nacos注册中心,解决了服务的注册与发现
  2. Ribbon客户端负载均衡器,解决了服务集群的负载均衡
  3. OpenFeign声明式的HTTPClient,解决服务远程调用的问题

你可能感兴趣的:(微服务相关,分布式)