Spring Cloud 04 - 负载均衡和外部服务访问

Ribbon & Feign

文章目录

  • Ribbon & Feign
    • 一:Ribbon负载均衡
      • 1:介绍
    • 2:ribbon的五大核心组件
    • 二:Feign外部接口访问
      • 1:Feign概述
      • 2:Feign vs OpenFeign
      • 3:使用示例
        • 3.1:注解支持
        • 3.2:yml配置
        • 3.3:主启动类添加注解
        • 3.4:消费注册中心的内容
        • 3.5:自动装配接口并消费
      • 4:其他控制
        • 4.1:OpenFeign超时控制
        • 4.2:OpenFeign日志打印功能
        • 4.3:Gzip压缩(了解)
        • 4.4:Http连接池(重要)
      • 5:请求拦截器RequestInterceptor
      • 6:Feign原理(动态代理)
    • 三:调用第三方接口的坑

一:Ribbon负载均衡

大佬的你好ribbon:https://blog.csdn.net/xiaomujiang_dafangzi/category_10515853.html

1:介绍

Ribbon其实就是一个软负载均衡客户端组件, 他可以和其他所需请求的客户端结合使用,和eureka结合只是其中一个实例.

在这里插入图片描述

2:ribbon的五大核心组件

  • 服务列表(全部的服务地址信息),过滤列表和更新列表(最新的注册表信息)
  • ping心跳检测服务的可用性
  • 负载均衡策略(轮询,随机,权重和响应速度)
    在这里插入图片描述

二:Feign外部接口访问

1:Feign概述

Feign

Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装HTTP请求报文的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。
Feign被广泛应用在Spring Cloud 的解决方案中,是学习基于Spring Cloud 微服务架构不可或缺的重要组件。

Feign 是Spring Cloud Netflix组件中的一量级Restful的 HTTP 服务客户端,实现了负载均衡和 Rest 调用的开源框架

Feign 封装了RibbonRestTemplate, 实现了WebService的面向接口编程,进一步降低了项目的耦合度。

什么是服务调用

服务调用就是服务之间的接口互相调用,在微服务架构中很多功能都需要调用多个服务才能完成某一项功能。

为什么要使用Feign

Feign 旨在使编写 JAVA HTTP 客户端变得更加简单,Feign 简化了RestTemplate代码,实现了Ribbon负载均衡,使代码变得更加简洁,也少了客户端调用的代码

使用 Feign 实现负载均衡是首选方案,只需要你创建一个接口,然后在上面添加注解即可。

Feign 是声明式服务调用组件,其核心就是:像调用本地方法一样调用远程方法,无感知远程 HTTP 请求

在这里插入图片描述

2:Feign vs OpenFeign

Feign 内置了Ribbon,用来做客户端负载均衡调用服务注册中心的服务,使用 Feign 的注解定义接口,然后调用这个接口,就可以调用服务注册中心的服务

Feign 本身并不支持 Spring MVC 的注解,它有一套自己的注解,为了更方便的使用 Spring Cloud 孵化了OpenFeign

OpenFeigin还支持了 Spring MVC 的注解,如@RequestMapping@PathVariable等等。

OpenFeign 的@FeignClient可以解析 Spring MVC 的 @RequestMapping 注解下的接口,通过动态代理方式产生实现类,实现类中做负载均衡调用服务。

3:使用示例

3.1:注解支持
<!--Feign相关-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId><version>1.4.7.RELEASE</version>
</dependency><!-- openFeign -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3.2:yml配置

声明eureka-server的地址

server:port: 80# eureka相关注解
eureka:client:register-with-eureka: falsefetch-registry: trueservice-url:defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
3.3:主启动类添加注解
package com.atguigu.springcloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
@EnableFeignClients // <-
public class OrderFeignMain80 {public static void main(String[] args) {SpringApplication.run(OrderFeignMain80.class,args);}
}
3.4:消费注册中心的内容

微服务调用接口 + @FeignClient

package com.atguigu.springcloud.service;import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;@Component
@FeignClient(value = "CLOUD-PAYMENT-SERVICE")
public interface PaymentFeignService {/*** 通过主键查询单条数据** @param id 主键* @return 单条数据*/@GetMapping("payment/selectOne/{id}")CommonResult<Payment> selectOne(@PathVariable("id") Long id);@GetMapping("payment/feign/timeout")String getFeignTimeOut();
}
3.5:自动装配接口并消费
package com.atguigu.springcloud.controller;import com.atguigu.springcloud.entities.CommonResult;
import com.atguigu.springcloud.entities.Payment;
import com.atguigu.springcloud.service.PaymentFeignService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@RequestMapping("order")
public class OrderFeignController {@Resourceprivate PaymentFeignService paymentFeignService;@GetMapping("selectOne/{id}")public CommonResult<Payment> selectOne(@PathVariable("id") Long id){return paymentFeignService.selectOne(id);}@GetMapping("/feign/timeout")public String getFeignTimeOut() {return paymentFeignService.getFeignTimeOut();}
}

4:其他控制

4.1:OpenFeign超时控制

默认的,feign客户端只等待1s,如果超过1s,将会直接报错,因此有时需要设置超时控制

要在yml文件中开启配置

server:port: 80
eureka:client:register-with-eureka: falsefetch-registry: trueservice-url:defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间ReadTimeout: 5000# 指的是建立连接后从服务器读取到可用资源所用的时间ConnectTimeout: 5000
4.2:OpenFeign日志打印功能

Feign提供了日志打印功能,可以调整对应打印的日志的级别,从而了解对http请求的细节

说白了就是对Feign接口的调用情况进行监控和输出

日志级别

  • None -> 默认的,不返回任何的日志
  • Basic -> 仅仅记录请求的方法,URL,相应状态码和执行的时间
  • Headers -> 除了Basic中记录的信息,还有请求和响应的头信息
  • Full -> 除了Headers中定义的信息之外,还有请求和响应的正文及元数据

配置bean

package com.atguigu.springcloud.config;import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** OpenFeignClient配置**/
@Configuration
public class FeignConfig {/*** feignClient配置日志级别*/@Beanpublic Logger.Level feignLoggerLevel() {// 请求和响应的头信息,请求和响应的正文及元数据return Logger.Level.FULL;}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import feign.Logger;
// ====== 在客户端接口指定此配置 ======/*** 用户服务*/
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class, // 失败策略configuration = FeignConfig.class) // 执行上面的配置
public interface RemoteUserService {
}

YML文件里需要开启日志的Feign客户端

server:port: 80
eureka:client:register-with-eureka: falsefetch-registry: trueservice-url:defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
# 设置feign客户端超时时间(OpenFeign默认支持ribbon)
ribbon:# 指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间ReadTimeout: 5000# 指的是建立连接后从服务器读取到可用资源所用的时间ConnectTimeout: 5000
logging:level:# feign日志以什么级别监控哪个接口com.atguigu.springcloud.service.PaymentFeignService: debug
4.3:Gzip压缩(了解)

gzip是一种数据格式,采用deflate算法压缩数据。gzip大约可以帮我们减少70%以上的文件大小。

全局配置Gzip

server:compression:# 是否开启压缩enabled: true# 配置支持压缩的 MIME TYPEmime-types: text/html,text/xml,text/plain,application/xml,application/json

局部配置

开启压缩可以有效节约网络资源,但是会增加CPU压力,建议把最小压缩的文档大小适度调大一点。

feign:compression:request:# 开启请求压缩enabled: true# 配置压缩支持的 MIME TYPEmime-types: text/xml,application/xml,application/json # 配置压缩数据大小的下限min-request-size: 2048   response:# 开启响应压缩enabled: true
4.4:Http连接池(重要)

两台服务器建立HTTP连接的过程涉及到多个数据包的交换,很消耗时间。采用HTTP连接池可以节约大量的时间提示吞吐量。

Feign的HTTP客户端支持3种框架:HttpURLConnectionHttpClientOkHttp

默认是采用java.net.HttpURLConnection,每次请求都会建立、关闭连接

为了性能考虑,可以引入httpclient、okhttp作为底层的通信框架。

例如将Feign的HTTP客户端工具修改为HttpClient

1:添加依赖

<!-- feign httpclient -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId>
</dependency>

2:全局配置

feign:httpclient:# 开启httpclientenabled: true

3:测试验证

启动后访问http://localhost:8888/user/pojo?userName=ry,返回正确数据表示测试通过

// RemoteUserService FeignClient
@GetMapping("/user/pojo")
public Object selectUser(SysUser user);// 消费端
@Autowired
private RemoteUserService remoteUserService;@GetMapping("/user/pojo")
public Object UserInfo(SysUser user) {return remoteUserService.selectUser(user);
}// 服务端
@GetMapping("/pojo")
public R<SysUser> selectUser(@RequestBody SysUser user) {return R.ok(userService.selectUserByUserName(user.getUserName()));
}

例如将Feign的HTTP客户端工具修改为OkHTTP

<!--OK http 的依赖 -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId>
</dependency>

开启连接池

# 在application.yml配置文件中开启Feign的连接池功能
feign:okhttp:enabled: true # 开启OKHttp功能

5:请求拦截器RequestInterceptor

在微服务应用中,通过feign的方式实现http的调用

可以通过实现feign.RequestInterceptor接口在feign执行后进行拦截,对请求头等信息进行修改。

例如项目中利用feign拦截器将本服务的userIduserNameauthentication传递给下游服务

package com.ruoyi.common.security.feign;import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import feign.RequestInterceptor;
import feign.RequestTemplate;/*** feign 请求拦截器,实现feign.RequestInterceptor* * @author ruoyi*/
@Component
public class FeignRequestInterceptor implements RequestInterceptor {/*** 要实现apply方法,对请求进行拦截*/@Overridepublic void apply(RequestTemplate requestTemplate) {// 获取http servlet请求HttpServletRequest httpServletRequest = ServletUtils.getRequest();if (StringUtils.isNotNull(httpServletRequest)) {Map<String, String> headers = ServletUtils.getHeaders(httpServletRequest);// 传递用户信息请求头,防止丢失String userId = headers.get(SecurityConstants.DETAILS_USER_ID);if (StringUtils.isNotEmpty(userId)) {requestTemplate.header(SecurityConstants.DETAILS_USER_ID, userId);}String userKey = headers.get(SecurityConstants.USER_KEY);if (StringUtils.isNotEmpty(userKey)) {requestTemplate.header(SecurityConstants.USER_KEY, userKey);}String userName = headers.get(SecurityConstants.DETAILS_USERNAME);if (StringUtils.isNotEmpty(userName)) {requestTemplate.header(SecurityConstants.DETAILS_USERNAME, userName);}String authentication = headers.get(SecurityConstants.AUTHORIZATION_HEADER);if (StringUtils.isNotEmpty(authentication)) {requestTemplate.header(SecurityConstants.AUTHORIZATION_HEADER, authentication);}// 配置客户端IPrequestTemplate.header("X-Forwarded-For", IpUtils.getIpAddr());}}
}
// ----------- 客户端工具类 ServletUtils 如下 -----------------
package com.ruoyi.common.core.utils;import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.text.Convert;
import reactor.core.publisher.Mono;/*** 客户端工具类** @author ruoyi*/
public class ServletUtils {/*** 获取String参数*/public static String getParameter(String name) {return getRequest().getParameter(name);}/*** 获取String参数*/public static String getParameter(String name, String defaultValue) {return Convert.toStr(getRequest().getParameter(name), defaultValue);}/*** 获取Integer参数*/public static Integer getParameterToInt(String name) {return Convert.toInt(getRequest().getParameter(name));}/*** 获取Integer参数*/public static Integer getParameterToInt(String name, Integer defaultValue) {return Convert.toInt(getRequest().getParameter(name), defaultValue);}/*** 获取Boolean参数*/public static Boolean getParameterToBool(String name) {return Convert.toBool(getRequest().getParameter(name));}/*** 获取Boolean参数*/public static Boolean getParameterToBool(String name, Boolean defaultValue) {return Convert.toBool(getRequest().getParameter(name), defaultValue);}/*** 获得所有请求参数** @param request 请求对象{@link ServletRequest}* @return Map*/public static Map<String, String[]> getParams(ServletRequest request) {final Map<String, String[]> map = request.getParameterMap();return Collections.unmodifiableMap(map);}/*** 获得所有请求参数** @param request 请求对象{@link ServletRequest}* @return Map*/public static Map<String, String> getParamMap(ServletRequest request) {Map<String, String> params = new HashMap<>();for (Map.Entry<String, String[]> entry : getParams(request).entrySet()) {params.put(entry.getKey(), StringUtils.join(entry.getValue(), ","));}return params;}/*** 获取request*/public static HttpServletRequest getRequest() {try {return getRequestAttributes().getRequest();} catch (Exception e) {return null;}}/*** 获取response*/public static HttpServletResponse getResponse() {try {return getRequestAttributes().getResponse();} catch (Exception e) {return null;}}/*** 获取session*/public static HttpSession getSession() {return getRequest().getSession();}/*** 获取请求属性*/public static ServletRequestAttributes getRequestAttributes() {try {RequestAttributes attributes = RequestContextHolder.getRequestAttributes();return (ServletRequestAttributes) attributes;} catch (Exception e) {return null;}}/*** 通过请求信息和key获取指定key的请求头*/public static String getHeader(HttpServletRequest request, String name) {String value = request.getHeader(name);if (StringUtils.isEmpty(value)) {return StringUtils.EMPTY;}return urlDecode(value);}/*** 通过请求信息获取请求头*/public static Map<String, String> getHeaders(HttpServletRequest request) {Map<String, String> map = new LinkedCaseInsensitiveMap<>();Enumeration<String> enumeration = request.getHeaderNames();if (enumeration != null) {while (enumeration.hasMoreElements()) {String key = enumeration.nextElement();String value = request.getHeader(key);map.put(key, value);}}return map;}/*** 将字符串渲染到客户端** @param response 渲染对象* @param string   待渲染的字符串*/public static void renderString(HttpServletResponse response, String string) {try {response.setStatus(200);response.setContentType("application/json");response.setCharacterEncoding("utf-8");response.getWriter().print(string);} catch (IOException e) {e.printStackTrace();}}/*** 是否是Ajax异步请求** @param request*/public static boolean isAjaxRequest(HttpServletRequest request) {String accept = request.getHeader("accept");if (accept != null && accept.contains("application/json")) {return true;}String xRequestedWith = request.getHeader("X-Requested-With");if (xRequestedWith != null && xRequestedWith.contains("XMLHttpRequest")) {return true;}String uri = request.getRequestURI();if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml")) {return true;}String ajax = request.getParameter("__ajax");return StringUtils.inStringIgnoreCase(ajax, "json", "xml");}/*** 内容编码** @param str 内容* @return 编码后的内容*/public static String urlEncode(String str) {try {return URLEncoder.encode(str, Constants.UTF8);} catch (UnsupportedEncodingException e) {return StringUtils.EMPTY;}}/*** 内容解码** @param str 内容* @return 解码后的内容*/public static String urlDecode(String str) {try {return URLDecoder.decode(str, Constants.UTF8);} catch (UnsupportedEncodingException e) {return StringUtils.EMPTY;}}/*** 设置webflux模型响应** @param response ServerHttpResponse* @param value    响应内容* @return Mono<Void>*/public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value) {return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL);}/*** 设置webflux模型响应** @param response ServerHttpResponse* @param code     响应状态码* @param value    响应内容* @return Mono<Void>*/public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value, int code) {return webFluxResponseWriter(response, HttpStatus.OK, value, code);}/*** 设置webflux模型响应** @param response ServerHttpResponse* @param status   http状态码* @param code     响应状态码* @param value    响应内容* @return Mono<Void>*/public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, HttpStatus status, Object value, int code) {return webFluxResponseWriter(response, MediaType.APPLICATION_JSON_VALUE, status, value, code);}/*** 设置webflux模型响应** @param response    ServerHttpResponse* @param contentType content-type* @param status      http状态码* @param code        响应状态码* @param value       响应内容* @return Mono<Void>*/public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, String contentType, HttpStatus status, Object value, int code) {response.setStatusCode(status);response.getHeaders().add(HttpHeaders.CONTENT_TYPE, contentType);R<?> result = R.fail(code, value.toString());DataBuffer dataBuffer = response.bufferFactory().wrap(JSON.toJSONString(result).getBytes());return response.writeWith(Mono.just(dataBuffer));}
}

6:Feign原理(动态代理)

  1. 基于面向接口的动态代理方式生成实现类:request bean -> target -> Contract
  2. 根据接口类的注解声明规则,解析出底层的MethodHandler
  3. 基于reqeust bean -> encode -> 请求
  4. 拦截器对请求进行装饰 -> 记录日志
  5. 基于重试器发送http请求 -> 向服务器发送请求报文

三:调用第三方接口的坑

在这里插入图片描述

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

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

相关文章

力扣--链表

相交链表 法一&#xff1a; 把A链表的节点都存HashSet里&#xff0c;遍历B链表找相同的节点 法二&#xff1a; 把A、B指针都移到末尾&#xff0c;再同时往回走&#xff0c;每次往回走都比较 当前节点的下一节点&#xff08;a.next b.next ?)是否相同&#xff0c;当不相同…

antd pro常见代码示例-ProTable

1、protable使用 这是antd Pro 封装的一个table组件&#xff0c;提供了很多好用的方法&#xff0c; proTable地址&#xff1a; protable官网 代码示例&#xff1a; <ProTableactionRef{actionRef}pagination{{ //分页设置defaultPageSize: 10,showQuickJumper: true,sh…

【C++】异常

前言 本篇博客我们来看下C有关异常的处理&#xff0c;了解下异常有关的知识 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;C 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 ​ 目录 1.异常的概念及使用 1.1异…

操作系统—进程与线程

补充知识 PSW程序状态字寄存器PC程序计数器&#xff1a;存放下一条指令的地址IR指令寄存器&#xff1a;存放当前正在执行的指令通用寄存器&#xff1a;存放其他一些必要信息 进程 进程&#xff1a;进程是进程实体的运行过程&#xff0c;是系统进行资源分配和调度的一个独立单位…

NIO--ByteBuffer组件

文章目录 概述ByteBuffer 正确使用姿势ByteBuffer 结构ByteBuffer 常见方法分配空间向 buffer 写入数据从 buffer 读取数据mark 和 reset字符串与 ByteBuffer 互转Scattering ReadsGathering Writes ⚠️ Buffer 的线程安全 概述 ByteBuffer就是缓冲区&#xff0c;作为channel…

软件工程的熵减:AI如何降低系统复杂度

软件开发的世界&#xff0c;如同一个不断膨胀的宇宙。随着功能的增加和时间的推移&#xff0c;代码库越来越庞大&#xff0c;系统复杂度也随之水涨船高。代码膨胀、维护困难、开发效率低下等问题困扰着无数开发者。这不禁让人联想到物理学中的“熵增”原理——一个孤立系统的熵…

xss闯关

BUU上的[第二章 web进阶]XSS闯关 第一关 第一关很简单&#xff0c;没有任何过滤&#xff0c;直接输入&#xff1a;<script>alert()</script>即可。 第二关 第二关可以输入xss和<script>alert()</script>分别查看页面源代码&#xff0c;看看哪里变了…

Postman接口测试:postman设置接口关联,实现参数化

postman设置接口关联 在实际的接口测试中&#xff0c;后一个接口经常需要用到前一个接口返回的结果&#xff0c; 从而让后一个接口能正常执行&#xff0c;这个过程的实现称为关联。 在postman中实现关联操作的步骤如下&#xff1a; 1、利用postman获取上一个接口指定的返回值…

从算法到落地:DeepSeek如何突破AI工具的同质化竞争困局

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ Linux网络编程笔记&#xff1a; https://blog.cs…

【通俗易懂说模型】反向传播(附多元回归与Softmax函数)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …

电脑黑屏按什么键恢复?电脑黑屏的解决办法

电脑黑屏的原因有很多&#xff0c;可能是硬件、软件、系统或者病毒等方面造成的。那么&#xff0c;当我们遇到电脑黑屏时&#xff0c;应该怎么做呢&#xff1f;有没有什么快捷的方法可以恢复正常呢&#xff1f;本文将为您介绍一些常见的电脑黑屏情况及其解决办法。 一、电脑开机…

多智能体协作架构模式:驱动传统公司向AI智能公司转型

前言 在数字化浪潮的席卷下&#xff0c;传统公司的运营模式正面临着前所未有的挑战。随着市场竞争的日益激烈&#xff0c;客户需求的快速变化以及业务复杂度的不断攀升&#xff0c;传统公司在缺乏 AI 技术支撑的情况下&#xff0c;暴露出诸多痛点。在决策层面&#xff0c;由于…

CNN 卷积神经网络处理图片任务 | PyTorch 深度学习实战

前一篇文章&#xff0c;学习率调整策略 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started CNN 卷积神经网络 CNN什么是卷积工作原理深度学习的卷积运算提取特征不同特征核的效果比较卷积核感受野共享权重池化 示例源码 …

云上考场微信小程序的设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

Intellij IDEA如何查看当前文件的类

快捷键&#xff1a;CtrlF12&#xff0c;我个人感觉记快捷键很麻烦&#xff0c;知道具体的位置更简单&#xff0c;如果忘了快捷键&#xff08;KeyMap&#xff09;看一下就记起来了&#xff0c;不需要再Google or Baidu or GPT啥的&#xff0c;位置&#xff1a;Navigate > Fi…

支持多种网络数据库格式的自动化转换工具——VisualXML

一、VisualXML软件介绍 对于DBC、ARXML……文件的编辑、修改等繁琐操作&#xff0c;WINDHILL风丘科技开发的总线设计工具——VisualXML&#xff0c;可轻松解决这一问题&#xff0c;提升工作效率。 VisualXML是一个强大且基于Excel表格生成多种网络数据库文件的转换工具&#…

Python Pandas(5):Pandas Excel 文件操作

Pandas 提供了丰富的 Excel 文件操作功能&#xff0c;帮助我们方便地读取和写入 .xls 和 .xlsx 文件&#xff0c;支持多表单、索引、列选择等复杂操作&#xff0c;是数据分析中必备的工具。 操作方法说明读取 Excel 文件pd.read_excel()读取 Excel 文件&#xff0c;返回 DataF…

查看云机器的一些常用配置

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes常…

网站改HTTPS方法

默认的网站建设好后打开的样子那看起来像是钓鱼网站&#xff0c;现在的浏览器特别只能&#xff0c;就是你新买来的电脑默认的浏览器同样也会出现这样“不安全”提示。 传输协议启动了向全球用户安全传输网页内容的流程。然而&#xff0c;随着HTTPS的推出&#xff0c;传输协议通…

ssti学习笔记(服务器端模板注入)

目录 一&#xff0c;ssti是什么 二&#xff0c;原理 所谓模板引擎&#xff08;三列&#xff0c;可滑动查看&#xff09; 三&#xff0c;漏洞复现 1&#xff0c;如何判断其所属的模板引擎&#xff1f; 2&#xff0c;判断清楚后开始注入 &#xff08;1&#xff09;Jinja2&a…