(一)Spring Cloud 直击微服务作用、架构应用、hystrix降级

直击微服务作用

  微服务架构:

    遇到了什么问题?
        将单体架构拆分成微服务架构后,如果保证多个服务(项目)正常运行?
    哪个技术可以解决这个问题?
        微服务技术
        服务治理: 服务管理,维护服务与服务之间的关系
    这个技术如何使用?
        netflix/网飞:
        SpringCloud: ★
        Alibaba: ★ 

软件架构

架构: 结构

软件架构: 软件的结构

淘宝架构演进过程:

100并发 -> 千万并发,阿里淘宝的 14 次架构演进之路!

软件架构演进过程:
    单体架构: All in one
        优点: 架构简单 部署方便
        缺点: 
            耦合度高,维护成本大
            技术栈受限
        使用场景: 用户量小,一般情况下开发学生管理系统
    分布式架构:
        将大项目拆分成多个小项目
    微服务架构:
        拆分原则:
            单一职责: 一个服务只做一件事情(不允许出现冗余的功能或模块)
            自治: 团队独立,技术独立,部署独立,数据库独立
            面向服务: 微服务开发完毕后,需要对外提供统一的访问接口(对接规范)
            隔离性强: 服务调用做好隔离、容错、降级,避免出现级联问题
微服务技术:
    各个公司将自己的单体架构的项目拆分成微服务架构项目后,都有自己的解决方案.我们学习时,主要学习SpringCloud官方提供的微服务组件,SpringCloud官方使用的组件主要来自NetFlix和Alibaba
    学习微服务其实就是学习相关的微服务组件,一个组件可以解决微服务拆分后的一类问题.

如何使用:

准备微服务环境
创建两个数据库,分别写一套对应的增删改查操作

依赖

     <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>Hoxton.SR10</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>

Eureka组件

遇到了什么问题?
    - order-service在发起远程调用的时候,该如何得知user-service实例的ip地址和端口?
    - 有多个user-service实例地址,order-service调用时该如何选择?
    - order-service如何得知某个user-service实例是否依然健康,是不是已经宕机?
哪个技术可以解决这个问题?
    Eureka组件可以解决
这个技术如何使用?
    1.搭建Eureka服务端
    2.在微服务中整合Eureka客户端
    3.在消费者方,通过服务名称获取提供者的地址,负载均衡进行访问

RestTemplate对象

RestTemplate: 模拟浏览器的行为向服务器发送请求


/*** @Author: huahua* @name:RestTemplateTest* @Date:2023/7/18 10:41*/
@SpringBootTest
public class RestTemplateTest {/*** RPC(Remote Procedure Call Protocol): 远程过程调用*      只要实现了两台机器之间的数据交互就可以称之为远程过程调用* RestTemplate: 封装了远程调用的客户端**/@Autowiredprivate RestTemplate restTemplate;// get方式的请求@Testpublic void test01(){// 向目标服务器发送请求,并接收对应的结果//String resp = restTemplate.getForObject("http://user-service/user/1", String.class);//TbUser resp = restTemplate.getForObject("http://user-service/user/1", TbUser.class);// 携带参数//TbUser resp = restTemplate.getForObject("http://user-service/user/findByName/柳岩", TbUser.class);//System.out.println(resp);ResponseEntity<TbUser> resp = restTemplate.getForEntity("http://127.0.0.1:8081/user/1", TbUser.class);// 获取响应状态HttpStatus statusCode = resp.getStatusCode();// 获取响应数据TbUser tbUser = resp.getBody();// 获取响应头HttpHeaders headers = resp.getHeaders();// 获取响应头中的cookie头List<String> list = headers.get("Set-Cookie");System.out.println(statusCode);System.out.println(tbUser);System.out.println(headers);System.out.println(list);}/*** 请求头设置参数,访问指定接口*/@Testpublic void test03(){String url="http://127.0.0.1:8081/user/2";//设置请求头参数HttpHeaders headers = new HttpHeaders();headers.add("token","damimi");//请求头填充到请求对象下HttpEntity<Map> entry = new HttpEntity<>(headers);//发送请求ResponseEntity<TbUser> responseEntity = restTemplate.exchange(url, HttpMethod.GET, entry, TbUser.class);TbUser result = responseEntity.getBody();System.out.println(result);}/*** post模拟form表单提交数据*/@Testpublic void test04(){String url="http://localhost:8081/user/save";//设置请求头,指定请求数据方式HttpHeaders headers = new HttpHeaders();//告知被调用方,请求方式是form表单提交,这样对方解析数据时,就会按照form表单的方式解析处理headers.add("Content-type","application/x-www-form-urlencoded");//组装模拟form表单提交数据,内部元素相当于form表单的input框LinkedMultiValueMap<String, Object> map = new LinkedMultiValueMap<>();map.add("username","迪丽热巴");map.add("address","天津");HttpEntity<LinkedMultiValueMap<String, Object>> httpEntity = new HttpEntity<>(map, headers);/*参数1:请求url地址参数2:请求方式 POST参数3:请求体对象,携带了请求头和请求体相关的参数参数4:响应数据类型*/ResponseEntity<TbUser> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, TbUser.class);TbUser body = exchange.getBody();System.out.println(body);}/*** post发送json数据*/@Testpublic void test05() throws JsonProcessingException {String url="http://localhost:8081/user/save2";//设置请求头的请求参数类型HttpHeaders headers = new HttpHeaders();//告知被调用方,发送的数据格式的json格式,对方要以json的方式解析处理headers.add("Content-type","application/json; charset=utf-8");//组装json格式数据HashMap<String, String> reqMap = new HashMap<>();reqMap.put("username","zhangsan");reqMap.put("address","上海");ObjectMapper objectMapper = new ObjectMapper();String reqMapJson = objectMapper.writeValueAsString(reqMap);//构建请求对象HttpEntity<String> httpEntity = new HttpEntity<>(reqMapJson, headers);/*发送数据参数1:请求url地址参数2:请求方式参数3:请求体对象,携带了请求头和请求体相关的参数参数4:响应数据类型*/ResponseEntity<TbUser> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, TbUser.class);//或者// Account account=restTemplate.postForObject(url,httpEntity,Account.class);TbUser body = responseEntity.getBody();System.out.println(body);}@Testpublic void test07(){ResponseEntity<String> resp = restTemplate.getForEntity("http://www.takungpao.com/news/index.html", String.class);String body = resp.getBody();System.out.println(body);}
}

Ribbon

当服务从Eureka中拉取多个服务地址时,Ribbon可以实现负载均衡(从多个地址中选择一个)
在RestTemplate对象上添加注解 @LoadBalanced

Hystrix组件

作用: 解决雪崩问题
      雪崩问题: 在一个业务链路中,由于下游服务的故障,导致整个链路关联的所以服务宕机.
解决方案:
    服务降级: 换一种方式快速给上游服务一个响应.
    服务熔断: 当出错率到达一定的阈值时,直接熔断,不再访问下游服务,直接降级.

服务降级

1.导入启动器

在消费者/上游服务方导入

 <!-- Hystrix启动器 -->
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

2.在引导上开启Hystrix支持

@EnableHystrix

3.编写降级逻辑

a.在需要降级的方法上降级注解: @HystrixCommand(fallbackMethod="降级方法名")
b.编写降级的方法
  降级处理的方法,与原方法返回值,参数列表保持一致

package com.bw.order.controller;import com.bw.order.domain.TbOrder;
import com.bw.order.domain.TbUser;
import com.bw.order.service.TbOrderService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @Author: huahaua* @name:OrderController* @Date:2023/8/14 18:48*/
@RestController
@RequestMapping("/order")
public class OrderController {@Autowiredprivate TbOrderService orderService;// 此方法执行超时后,调用对应降级的方法快速处理业务@RequestMapping("/findById/{id}")@HystrixCommand(fallbackMethod="findUserByIdForFail")public TbOrder findById(@PathVariable Integer id){TbOrder order = orderService.findById(id);return order;}// todo:降级处理的方法,与原方法返回值,参数列表保持一致public TbOrder findUserByIdForFail(Integer id){TbOrder order = new TbOrder();order.setName("你的小可爱走丢了....服务降级");return order;}
}

4.注意事项和配置

Hystrix默认降级时间为1秒钟
配置降级时间:

hystrix:command:default:execution.isolation.thread.timeoutInMilliseconds: 2000 # 单位毫秒

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言:输入成绩,统计不及格人数|练习题

一、题目 输入学生成绩&#xff0c;统计不及格的学生人数 二、代码截图【带注释】 三、源代码【带注释】 #include <stdio.h> //题目&#xff1a;输入成绩&#xff0c;统计不及格人数 //思考分析 //1、由于学生人数是未知数&#xff0c;所以可以在输入时&#xff0c;以0…

vue2源码解析之第一步(对数据进行劫持)

###环境搭建 第一步 创建项目&#xff1a; npm init -y 第二步 安装对应的插件&#xff1a; npm i rollup rollup-plugin-babel babel/core babel/preset-env --save-dev 第三步 全局下创建rollup配置文件 rollup.config.js import babel from rollup-plug…

【开源】基于JAVA、微信小程序的音乐平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示 四、核心代码4.1 查询单首音乐4.2 新增音乐4.3 新增音乐订单4.4 查询音乐订单4.5 新增音乐收藏 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的音乐平台&#xff0c;包含了音乐…

用通俗易懂的方式讲解:大模型 RAG 在 LangChain 中的应用实战

Retrieval-Augmented Generation&#xff08;RAG&#xff09;是一种强大的技术&#xff0c;能够提高大型语言模型&#xff08;LLM&#xff09;的性能&#xff0c;使其能够从外部知识源中检索信息以生成更准确、具有上下文的回答。 本文将详细介绍 RAG 在 LangChain 中的应用&a…

外汇天眼:

随着年关将近&#xff0c;各种电信诈骗也层出不穷&#xff0c;令人防不胜防。 上个月&#xff0c;台北市警方就接到辖区内银行的诈骗通报&#xff0c;得知竟有民众被骗走新台币1亿元以上&#xff0c;这究竟是怎么回事呢&#xff1f; 根据警方掌握到的情报&#xff0c;受害者是…

最新Python安装和pycharm使用

1,进入python官网,点击download下载 2,双击默认下一步进行安装,并勾选添加环境变量 3,全选安装 ,4,安装完成,关闭即可 5,使用命令窗口测试版本 =======================================

JavaScript日期和时间处理手册

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ ✨ 前言 日期和时间在应用开发中是非常常用的功能。本文将全面介绍JavaScript中处理日期和时间的方…

MT36291 2.5A 高效的1.2MHz电流模式升压转换器 DCDC管理芯片 航天民芯

描述 MT36291是一个恒定频率、6引脚SOT23电流模式升压转换器&#xff0c;旨在用于小型、低功耗的应用。MT36291的开关频率为1.2MHz&#xff0c;并允许使用2mm或更低高度的微小、低成本的电容器和电感器。内部软启动导致注入电流小&#xff0c;延长电池寿命。MT36291的特点是在光…

openssl3.2 - 自己构建openssl.exe的VS工程(在编译完的源码版本上)

文章目录 openssl3.2 - 自己构建openssl.exe的VS工程(在编译完的源码版本上)概述笔记备注END openssl3.2 - 自己构建openssl.exe的VS工程(在编译完的源码版本上) 概述 将openssl3.2编译出来了(openssl3.2 - 编译) 安装后的openssl.exe可以干openssl3.2所有的事情, 用openssl.…

在VSCode中安装使用Copilot

在VSCode里找到扩展 安装好后登录github&#xff0c;授权 在VSCode里初步尝试 创建一个js文件 写一个函数名 在括号里回车&#xff0c;会出现可能的代码 如果觉得可以&#xff0c;按一下tab后&#xff0c;代码变亮

探索 OceanBase 中图数据的实现

在数据管理和处理的现代环境中&#xff0c;对能够处理复杂数据结构的复杂数据模型和方法的需求从未如此迫切。图数据的出现以其自然直观地表示复杂关系的独特能力&#xff0c;开辟了数据分析的新领域。 虽然 Neo4j 等成熟的图形数据库为处理图形数据提供了强大的解决方案&…

BabylonJS 6.0文档 Deep Dive 摄像机(三):自定义摄像机输入

1. 如何自定义摄像机输入 当你调用摄像机的attachControl方法之后&#xff0c;摄像机都会自动为您处理输入。可以使detachControl方法撤消该控件。大多数Babylon.js专家使用两步流程来激活和连接相机&#xff1a; //First, set the scenes activeCamera... to be YOUR camera…