从0到1构建自己的短链接系统

1. 短链系统简介

1.1 短链系统的定义与用途

短链系统是指将一个较长的URL地址,通过特定的算法生成一个较短的、具备唯一性的URL地址。这种系统广泛应用于社交网络、短信、邮件营销等场景,它能帮助用户在字数受限的情况下分享链接,并且还具有一定的数据统计与分析功能。

1.2 短链系统的核心功能

一个完善的短链系统通常包括以下核心功能:

  • 短链接生成:将长链接转换成短链接,并保证短链接的唯一性与高效性。
  • 短链接访问:通过短链接重定向到原始长链接,保证用户能访问到目标地址。
  • 数据统计:统计每个短链接的点击次数、IP、来源等数据,方便后续的分析和优化。
  • 链接管理:提供接口或后台系统,便于用户管理和查看生成的短链接。

1.3 短链系统的架构设计概述

为了实现上述功能,我们需要对系统的架构进行详细设计,系统各部分的职责与协作模式需要明确。总体上,短链系统的架构可以分为以下几个部分:

  • API层:提供生成短链接和解析短链接的接口。
  • 服务层:处理短链接的生成与解析逻辑。
  • 数据层:负责长链接与短链接的存储及管理,可以使用数据库或者缓存系统。
  • 缓存层:提高系统性能,常用缓存系统如Redis可以在短链频繁被访问时减少直接数据库查询的压力。

2. 系统设计

在设计一个短链系统时,我们需要考虑到短链接的生成算法、数据存储方案以及短链接的访问与解析流程。合理的设计能确保系统的稳定性和高效性。

  • 短链接生成时序图

file

  • 短链接解析时序图

file

2.1 短链接生成算法

短链接的生成是短链系统的核心功能之一,设计一个高效的生成算法至关重要。在这里我们介绍两种常用的算法:哈希算法和Base62编码。

2.1.1 哈希算法

哈希算法通过对长链接进行哈希计算,生成一个固定长度的字符串。常用的哈希算法有MD5、SHA-1等。哈希算法简单高效,但由于哈希比特位较长而不适用于直接生成短链接。为了获得更短的链接,我们通常需要结合Base62编码使用。

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;public class HashUtil {public static String getMD5(String url) {try {MessageDigest md = MessageDigest.getInstance("MD5");byte[] array = md.digest(url.getBytes());StringBuilder sb = new StringBuilder();for (byte b : array) {sb.append(String.format("%02x", b));}return sb.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();return null;}}
}

2.1.2 Base62编码

Base62编码是一种将字节数组转换为可读字符串的技术,它使用62个字符(0-9, a-z, A-Z)表示不同的值。Base62编码生成的字符串较短,非常适合作为短链接。
以下是Base62编码的示例代码:

public class Base62 {private static final String BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";public static String encode(long value) {StringBuilder sb = new StringBuilder();while (value != 0) {sb.append(BASE62.charAt((int) (value % 62)));value /= 62;}return sb.reverse().toString();}public static long decode(String shortLink) {long result = 0;for (char c : shortLink.toCharArray()) {result = result * 62 + BASE62.indexOf(c);}return result;}
}

2.2 数据存储方案

选择合适的数据存储方案对于短链系统的性能和稳定性至关重要。常用的存储方案有关系数据库和NoSQL数据库。

2.2.1 NoSQL数据库选择

考虑到短链系统需要高并发和快速读写的特性,NoSQL数据库是一个不错的选择。常用的NoSQL数据库有Redis、MongoDB等。
在这里,我们选择Redis作为存储方案,因其高效的读写性能和丰富的数据类型支持。

2.2.2 数据库表设计

在设计数据库表时,我们需要考虑到短链接与长链接的映射关系。一个简单的设计如下:

  • 短链接表 (ShortLink):用于存储短链接与长链接的映射关系。
  • id:自增主键
  • short_link:短链接
  • long_link:长链接
  • create_time:创建时间
  • expire_time:过期时间(可选)
CREATE TABLE ShortLink (id BIGINT AUTO_INCREMENT PRIMARY KEY,short_link VARCHAR(10) NOT NULL,long_link TEXT NOT NULL,create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,expire_time TIMESTAMP
);

2.3 短链接访问与解析

短链系统在生成短链接后,还需处理短链接的访问与解析。

2.3.1 短链访问流程

当用户访问一个短链接时,系统需要解析该短链接并重定向到对应的长链接。流程如下:

  • 1.接收到短链接访问请求。
  • 2.查找短链接对应的长链接(缓存优先,缓存未命中则访问数据库)。
  • 3.将请求重定向到长链接。

2.3.2 缓存机制

为提升访问速度和减轻数据库压力,我们可以引入缓存机制。常用缓存系统如Redis 允许我们快速查找短链接。缓存机制的设计包括:

  • 缓存策略:使用设置超时时间的LRU策略。
  • 缓存更新:生成短链接时将映射关系写入缓存。
public class ShortLinkService {private final RedisTemplate<String, String> redisTemplate;private final ShortLinkRepository shortLinkRepository; // 假设有一个Repository处理数据库操作public ShortLinkService(RedisTemplate<String, String> redisTemplate, ShortLinkRepository shortLinkRepository) {this.redisTemplate = redisTemplate;this.shortLinkRepository = shortLinkRepository;}public String getLongLink(String shortLink) {String longLink = redisTemplate.opsForValue().get(shortLink);if (longLink == null) {// 缓存未命中,从数据库查找longLink = shortLinkRepository.findLongLinkByShortLink(shortLink);if (longLink != null) {// 更新缓存redisTemplate.opsForValue().set(shortLink, longLink);}}return longLink;}
}

3. 系统实现

在这一章节中,我们将详细讲解如何在Java中设计并实现一个短链系统。从项目初始化到各个功能模块的具体实现,都会详细阐述。

3.1 项目初始化与环境搭建

首先,我们需要创建一个新的Spring Boot项目,并进行基本的环境配置。

  • 项目目录结构
short-url/
├── src/
│   ├── main/
│   │   ├── java/com/example/shorturl/
│   │   │   ├── controller/
│   │   │   ├── entity/
│   │   │   ├── repository/
│   │   │   ├── service/
│   │   │   ├── ShortUrlApplication.java
│   │   ├── resources/
│   │   │   ├── application.properties
│   │   │   ├── schema.sql
│   │   │   ├── data.sql
└── pom.xml
  • 依赖管理

在pom.xml文件中添加必要的依赖,包括Spring Boot、Spring Data JPA、Redis等。

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
</dependencies>
  • 配置文件

在application.properties中配置数据库和Redis连接信息:

spring.datasource.url=jdbc:mysql://localhost:3306/short_url?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=yourpasswordspring.redis.host=localhost
spring.redis.port=6379

3.2 实体类设计

设计短链接与长链接映射的实体类。

package com.example.shorturl.entity;import javax.persistence.*;
import java.time.LocalDateTime;@Entity
@Table(name = "short_link")
public class ShortLink {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "short_link", nullable = false, unique = true)private String shortLink;@Column(name = "long_link", nullable = false)private String longLink;@Column(name = "create_time", nullable = false)private LocalDateTime createTime;@Column(name = "expire_time")private LocalDateTime expireTime;// Getters and Setters
}

3.3 服务层实现

服务层负责核心业务逻辑的实现,包括短链接的生成和解析。

3.3.1 短链接生成服务

实现短链接生成服务,包括长链接输入、短链接生成以及数据存储。

package com.example.shorturl.service;import com.example.shorturl.entity.ShortLink;
import com.example.shorturl.repository.ShortLinkRepository;
import com.example.shorturl.util.Base62;
import com.example.shorturl.util.HashUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;@Service
public class ShortLinkService {@Autowiredprivate ShortLinkRepository shortLinkRepository;@Autowiredprivate RedisTemplate<String, String> redisTemplate;public String createShortLink(String longLink) {String md5Hash = HashUtil.getMD5(longLink);String shortLink = Base62.encode(md5Hash.hashCode());ShortLink link = new ShortLink();link.setShortLink(shortLink);link.setLongLink(longLink);link.setCreateTime(LocalDateTime.now());shortLinkRepository.save(link);redisTemplate.opsForValue().set(shortLink, longLink);return shortLink;}public String getLongLink(String shortLink) {String longLink = redisTemplate.opsForValue().get(shortLink);if (longLink == null) {ShortLink link = shortLinkRepository.findByShortLink(shortLink);if (link != null) {longLink = link.getLongLink();redisTemplate.opsForValue().set(shortLink, longLink);}}return longLink;}
}

3.3.2 短链接解析服务

短链接解析服务负责通过短链接获取对应的长链接,并实现缓存机制。

package com.example.shorturl.service;import com.example.shorturl.entity.ShortLink;
import com.example.shorturl.repository.ShortLinkRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.concurrent.TimeUnit;@Service
public class ShortLinkService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Autowiredprivate ShortLinkRepository shortLinkRepository;public String getLongLink(String shortLink) {// 从Redis缓存中获取长链接String longLink = redisTemplate.opsForValue().get(shortLink);if (longLink == null) {// 缓存未命中,从数据库查找ShortLink link = shortLinkRepository.findByShortLink(shortLink);if (link != null) {longLink = link.getLongLink();// 将长链接存放到缓存中,有效期为24小时redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS);}}return longLink;}
}

3.4 控制层实现

控制层负责处理HTTP请求,将请求数据传递给服务层,并返回结果。

3.4.1 创建短链接的API

实现创建短链接的API,将长链接转化为短链接并返回。

package com.example.shorturl.controller;import com.example.shorturl.service.ShortLinkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api")
public class ShortLinkController {@Autowiredprivate ShortLinkService shortLinkService;@PostMapping("/shorten")public String createShortLink(@RequestParam String longLink) {return shortLinkService.createShortLink(longLink);}
}

3.4.2 访问短链接的API

实现访问短链接的API,通过短链接获取长链接并重定向。

package com.example.shorturl.controller;import com.example.shorturl.service.ShortLinkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@RestController
@RequestMapping("/s")
public class RedirectController {@Autowiredprivate ShortLinkService shortLinkService;@GetMapping("/{shortLink}")public void redirect(@PathVariable String shortLink, HttpServletResponse response) throws IOException {String longLink = shortLinkService.getLongLink(shortLink);if (longLink != null) {response.sendRedirect(longLink);} else {response.sendError(HttpServletResponse.SC_NOT_FOUND);}}
}

3.5 缓存层实现

使用Redis实现缓存,提升系统性能。

3.5.1 使用Redis进行缓存

在服务层使用Redis对长链接进行缓存。

@Autowired
private RedisTemplate<String, String> redisTemplate;

3.5.2 缓存策略

采用LRU策略,实现缓存有效期设置为24小时。

redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS);

4. 系统测试与优化

在完成短链系统的设计与实现之后,接下来需要对系统进行全面的测试和优化,确保系统的稳定性和高效性。

4.1 单元测试

单元测试是保证系统稳定性的重要环节。通过对各个模块进行单元测试,我们可以验证每个模块的功能是否符合预期。

4.1.1 服务层测试

写一个简单的测试类,对短链接生成服务和解析服务进行测试。

package com.example.shorturl;import com.example.shorturl.service.ShortLinkService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class ShortLinkServiceTests {@Autowiredprivate ShortLinkService shortLinkService;@Testpublic void testCreateShortLink() {String longLink = "https://www.example.com";String shortLink = shortLinkService.createShortLink(longLink);Assertions.assertNotNull(shortLink);}@Testpublic void testGetLongLink() {String longLink = "https://www.example.com";String shortLink = shortLinkService.createShortLink(longLink);String retrievedLongLink = shortLinkService.getLongLink(shortLink);Assertions.assertEquals(longLink, retrievedLongLink);}
}

4.1.2 控制层测试

使用MockMvc对控制层进行测试,确保API的正确性。

package com.example.shorturl;import com.example.shorturl.controller.ShortLinkController;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;@SpringBootTest
@AutoConfigureMockMvc
public class ShortLinkControllerTests {@Autowiredprivate MockMvc mockMvc;@Testpublic void testCreateShortLink() throws Exception {mockMvc.perform(post("/api/shorten").contentType(MediaType.APPLICATION_FORM_URLENCODED).param("longLink", "https://www.example.com")).andExpect(status().isOk());}@Testpublic void testRedirect() throws Exception {String shortLink = mockMvc.perform(post("/api/shorten").contentType(MediaType.APPLICATION_FORM_URLENCODED).param("longLink", "https://www.example.com")).andReturn().getResponse().getContentAsString();mockMvc.perform(get("/s/" + shortLink)).andExpect(status().is3xxRedirection());}
}

4.2 性能优化

在完成基本功能和测试之后,我们需要对系统进行性能优化,以提高其在高并发环境下的响应速度和稳定性。

4.2.1 数据库优化

针对数据库的优化,可以考虑以下几种方法:

  • 索引优化:为短链接和长链接表添加合适的索引,提高查询效率。
CREATE INDEX idx_short_link ON short_link(short_link);
CREATE INDEX idx_long_link ON short_link(long_link);
  • 读写分离:使用主从复制和读写分离技术,将读操作分散到从库,从而减轻主库压力。

4.2.2 缓存优化

缓存是提升系统性能的重要手段,通过合理利用缓存,可以减少数据库查询次数,提高系统的响应速度。

  • 缓存穿透:对每个访问短链接的请求进行缓存,防止缓存穿透。如果短链接不存在,可以缓存一个特殊的值(如空字符串),并设置合理的过期时间。
public String getLongLink(String shortLink) {String longLink = redisTemplate.opsForValue().get(shortLink);if (longLink == null) {longLink = shortLinkRepository.findByShortLink(shortLink);if (longLink != null) {redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS);} else {// 缓存空结果,防止缓存穿透redisTemplate.opsForValue().set(shortLink, "", 1, TimeUnit.HOURS);}}return "".equals(longLink) ? null : longLink;
}
  • 缓存雪崩:通过设置不同的缓存过期时间,避免大量缓存同时失效导致的缓存雪崩问题。
random = new Random();
long expireTime = 24 + random.nextInt(12); // 设置24-36小时的随机有效时间
redisTemplate.opsForValue().set(shortLink, longLink, expireTime, TimeUnit.HOURS);
  • 热点缓存:对于访问频率高的短链接,可以采用更长的缓存有效时间,减少缓存的频繁刷新。
if (isHotLink(shortLink)) {redisTemplate.opsForValue().set(shortLink, longLink, 72, TimeUnit.HOURS); // 热点链接缓存72小时
} else {redisTemplate.opsForValue().set(shortLink, longLink, 24, TimeUnit.HOURS); // 普通链接缓存24小时
}// 判断是否为热点链接的简单实现
private boolean isHotLink(String shortLink) {// 这里可以根据访问频率或其他指标来判断return shortLink.startsWith("hot");
}

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

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

相关文章

Jenkins 创建流水线任务

Jenkins是一个流行的持续集成&#xff08;Continuous Integration&#xff0c;CI&#xff09;工具。 Jenkins 创建任务 选择“流水线”类型&#xff0c;该类型的优点是定制化程度非常高 &#xff08;可选&#xff09;添加“参数化构建” 配置仓库选项(ssh连接、分支)和凭据…

上古世纪台服注册账号+下载客户端全方位图文教程

又一款新的MMRPG游戏即将上线啦&#xff0c;游戏名称叫做《上古世纪》游戏采用传统MMO类型游戏的玩法&#xff0c;但是开发商采用了先进的游戏引擎&#xff0c;让玩家们可以享受到极致的视觉体验。同时游戏的背景是建立在大陆分崩离析的基础上。各个部落因为领地的原因纷纷开战…

设计模式——责任链

责任链模式是一种行为设计模式&#xff0c;用于将请求的发送者和接收者解耦。在这种模式中&#xff0c;请求通过一条由多个对象组成的链传递&#xff0c;直到有一个对象能够处理该请求为止。每个对象都可以决定是否处理请求以及是否将请求传递给下一个对象。 责任链模式通常在…

螺丝扭断力试验机SJ-12

一、设备简介&#xff1a; 螺丝扭断力试验机用于测试螺丝的耐扭断力。本机将螺丝产品所受到轴向扭转力与反作用力&#xff0c;常用扭力扳手来计量。本机可对产品进行转力测、锁动测试、锁动扭力测试等多种测试方式。 二、设备使用&#xff1a; 1、将螺丝强度扭力试验机底座锁于…

代码随想录-Day41

46. 携带研究材料&#xff08;第六期模拟笔试&#xff09; 题目描述 小明是一位科学家&#xff0c;他需要参加一场重要的国际科学大会&#xff0c;以展示自己的最新研究成果。他需要带一些研究材料&#xff0c;但是他的行李箱空间有限。这些研究材料包括实验设备、文献资料和实…

Mysql数据库学习

1、数据库基本认知 一&#xff1a;数据库分类 关系型数据库&#xff1a;SQL 主要有MySQL,Oracle,Sql Server等&#xff0c;其主要通过表与表之间&#xff0c;行与列之间的关系进行数据的存储。可以通过外键来建立表之间的关联。 非关系型数据库&#xff1a;NoSQL 主要有HB…

分享一个 MySQL 简单快速进行自动备份和还原的脚本和方法

前言 数据备份和还原在信息技术领域中具有非常重要的作用&#xff0c;不论是人为误操作、硬件故障、病毒感染、自然灾害还是其他原因&#xff0c;数据丢失的风险都是存在的。如果没有备份&#xff0c;一旦数据丢失&#xff0c;可能对个人、企业甚至整个组织造成巨大的损失。 …

uniapp H5端使用百度地图

1、登录百度地图开放平台 https://lbsyun.baidu.com/&#xff08;没有账号则先去创建一个百度账号&#xff09; 2、进入百度地图开放平台控制台&#xff08;导航栏“控制台”&#xff09;&#xff0c;点击“应用管理”-“我的应用” 3、选择“创建应用”&#xff0c;应用模块选…

msvcr110.dll丢失的解决方法,亲测有效的几种解决方法

最近&#xff0c;我在启动一个程序时&#xff0c;系统突然弹出一个错误提示&#xff0c;告诉我电脑缺失了一个名为msvcr110.dll的文件。这让我感到非常困惑&#xff0c;因为我之前从未遇到过这样的问题。经过一番搜索和尝试&#xff0c;我总结了5种靠谱的解决方法。下面分享给大…

高效运维:标准化与智能化的运维流程管理实践

高效运维&#xff1a;标准化与智能化的运维流程管理实践 在信息化建设日益深化的今天&#xff0c;运维流程管理已成为企业确保其信息系统稳定、高效运行的关键手段。通过系统化、标准化的运维流程管理&#xff0c;企业能够有效预防系统故障&#xff0c;提升服务质量&#xff0…

React的路由(ReactRouter)-路由导航跳转

1.第一步 // createBrowserRouter路由 RouterProvider组件 import {createBrowserRouter,RouterProvider} from react-router-dom // 创建router实例对象&#xff0c;并配置路由对应关系 const routercreateBrowserRouter([{path:/login,element:<div>我是登录页</di…

vue3-登录小案例(借助ElementPlus+axios)

1.创建一个vue3的项目。 npm create vuelatest 2.引入Elementplus组件库 链接&#xff1a;安装 | Element Plus npm install element-plus --save 在main.js中引入 import ElementPlus from "element-plus";import "element-plus/dist/index.css";ap…

python--序列化模块json与pickle

什么叫序列化&#xff1f; 将原本的字典、列表等内容转换成一个字符串的过程就 叫做序列化。 多用的两个序列化模块&#xff1a;json与pickle json&#xff0c;用于字符串 和 python数据类型间进行转换 pickle&#xff0c;用于python特有的类型 和 python的数据类型间进行转换 …

Scania斯堪尼亚SHL题库综合能力性格测试真题题型解析及面试经验

一、走进Scania斯堪尼亚 Scania是一家成立于1891年的瑞典公司&#xff0c;专注于重型卡车和巴士的制造&#xff0c;以其模块化系统和环保设计闻名。作为全球领先的运输解决方案提供商&#xff0c;Scania不仅提供高质量的车辆&#xff0c;还提供相关服务和融资解决方案。公司秉…

Ruby langchainrb gem and custom configuration for the model setup

题意&#xff1a;Ruby 的 langchainrb gem 以及针对模型设置的自定义配置 问题背景&#xff1a; I am working in a prototype using the gem langchainrb. I am using the module assistant module to implemente a basic RAG architecture. 我正在使用 langchainrb 这个 ge…

实战|记一次java协同办公OA系统源码审计

前言 因为笔者也是代码审计初学者&#xff0c;写得不好的地方请见谅。该文章是以项目实战角度出发&#xff0c;希望能给大家带来启发。 审计过程 审计思路 1、拿到一个项目首先要看它使用了什么技术框架&#xff0c;是使用了ssh框架&#xff0c;还是使用了ssm框架&#xff…

C#基于SkiaSharp实现印章管理(2)

上一篇文章最后提到基于System.Text.Json能够序列化SKColor对象&#xff0c;但是反序列化时却无法解析本地json数据。换成Newtonsoft.Json进行序列化和反序列化也是类似的问题。   通过百度及查看微软的帮助文档&#xff0c;上述情况下需自定义转换类以处理SKColor类型数据的…

搜维尔科技:【研究】触觉手套比控制器更能带来身临其境、更安全、更高效的虚拟体验

自然交互可提高VR模拟的有效性。研究表明&#xff0c;触觉手套比控制器更能带来身临其境、更安全、更高效的虚拟体验。 以下是验证 医疗培训中的触觉技术 “ 95.5%的参与者表示触摸是 XR 教育的重要组成部分&#xff0c;90.9% 的参与者表示 XR 触觉将提供一个安全的学习场所。…

经典文献阅读之--MobileViT(轻量级、通用且移动友好的网络框架)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务&#xff0c;并且需要GPU资源&#xff0c;可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU&#xff0c;按时收费每卡2.6元&#xff0c;月卡只需要1.7元每小时&…

尚品汇-(七)

&#xff08;1&#xff09;在网关中实现跨域 全局配置类实现 包名&#xff1a;com.atguigu.gmall.gateway.config 创建CorsConfig类 Configuration public class CorsConfig {Beanpublic CorsWebFilter corsWebFilter(){// cors跨域配置对象CorsConfiguration configuration…