在.NETCore中从Redis迁移到本地内存中缓存:分步指南

程序员有二十年 2024-08-24 14:17:25

作为一名全栈开发人员,我最近在 .NET Core 项目中完成了从 Redis 过渡到内存缓存的过程。这种转变的驱动力是需要简化我们的架构并提高特定方案的性能。在本文中,我将指导你完成此迁移的步骤,提供编码做法,并演示在微服务体系结构中使用 .NET Core 后端和 TypeScript 前端的实际方案。

为什么要迁移到内存中缓存?

虽然 Redis 是一种强大的缓存解决方案,但内存中缓存在某些情况下可以提供优势,例如:

单纯: 通过消除对单独缓存服务器的需求,降低了基础架构的复杂性。

性能: 更快的访问时间,因为数据直接存储在应用程序的内存中。

成本: 通过消除维护和扩展 Redis 实例的需要来降低运营成本。

分步迁移1. 调整架构

我们的架构基本保持不变,只是我们用内存缓存替换了 Redis:

用户服务: 处理与用户相关的操作。

功能服务: 管理新的缓存功能及其逻辑。

API网关: 将请求路由到相应的服务。

前端应用: 与后端服务交互。

内存中缓存: 充当缓存层。

2. 在 .NET Core 中设置内存中缓存添加必要的软件包

请确保 .NET Core 项目中具有所需的包。

dotnet add package Microsoft.Extensions.Caching.Memory配置 In-Memory 缓存

在文件中配置内存中缓存。Startup.cs

// Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); services.AddScoped<IFeatureService, FeatureService>(); services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddControllers(); }在服务中实现缓存

更新服务以使用内存中缓存。

// FeatureService.cspublic FeatureService : IFeatureService{private readonly AppDbContext _context;private readonly IMemoryCache _cache;public FeatureService(AppDbContext context, IMemoryCache cache) { _context = context; _cache = cache; }public async Task<FeatureResponse> ProcessFeatureAsync(FeatureRequest request) {var cacheKey = $"Feature-{request.Input}";if (_cache.TryGetValue(cacheKey, out FeatureResponse cachedData)) {return cachedData; }// Simulate processingvar result = new FeatureResponse { Success = true, Message = "Feature processed successfully" }; _cache.Set(cacheKey, result, new MemoryCacheEntryOptions { AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5) });return result; }}设置控制器// FeatureController.cs[ApiController][Route("api/[controller]")]public FeatureController : ControllerBase{private readonly IFeatureService _featureService;public FeatureController(IFeatureService featureService) { _featureService = featureService; } [HttpPost]public async Task<IActionResult> ProcessFeature([FromBody] FeatureRequest request) {var response = await _featureService.ProcessFeatureAsync(request);return Ok(response); }}3. 开发前端

我们继续使用带有 TypeScript 的 React 作为前端应用程序。

设置 API 服务// apiService.tsimport axios from 'axios';export const processFeature = async (data: FeatureRequest) => { try { const response = await axios.post<FeatureResponse>('/api/feature', data); return response.data; } catch (error) { throw new Error('Failed to process feature'); }};创建 React 组件// FeatureComponent.tsximport React, { useState } from 'react';import { processFeature } from './apiService';const FeatureComponent: React.FC = () => { const [input, setInput] = useState(''); const [message, setMessage] = useState(''); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); try { const response = await processFeature({ input }); setMessage(response.message); } catch (error) { setMessage('Error processing feature'); } }; return ( <div> <form onSubmit={handleSubmit}> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} /> <button type="submit">Submit</button> </form> {message && <p>{message}</p>} </div> );};export default FeatureComponent;创建 React 组件// FeatureComponent.tsximport React, { useState } from 'react';import { processFeature } from './apiService';const FeatureComponent: React.FC = () => { const [input, setInput] = useState(''); const [message, setMessage] = useState(''); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); try { const response = await processFeature({ input }); setMessage(response.message); } catch (error) { setMessage('Error processing feature'); } }; return ( <div> <form onSubmit={handleSubmit}> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} /> <button type="submit">Submit</button> </form> {message && <p>{message}</p>} </div> );};export default FeatureComponent;4. 测试和部署

在实现内存中缓存后,我们进行了彻底的测试:

单元测试: 确保各个组件按预期工作。

集成测试: 验证服务之间的交互。

性能测试: 衡量内存中缓存对响应时间的影响。

用户验收测试 (UAT): 让真实用户参与验证解决方案。

最后,我们分阶段部署了新的缓存机制,从有限的 beta 版本开始。

编码实践和真实世界场景

以下是一些基于我们的迁移经验的编码实践和示例:

在 .NET Core 中使用依赖项注入Using Dependency Injection in .NET Core

依赖关系注入 (DI) 有助于管理依赖关系并促进干净的架构。

public void ConfigureServices(IServiceCollection services) { services.AddMemoryCache(); services.AddScoped<IFeatureService, FeatureService>(); services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddControllers(); }在 TypeScript 中处理 API 请求

使用 Axios 处理 API 请求提供了一种干净简单的方法来处理 HTTP 请求。

import axios from 'axios'; interface FeatureRequest { input: string; } interface FeatureResponse { success: boolean; message: string; } export const processFeature = async (data: FeatureRequest): Promise<FeatureResponse> => { try { const response = await axios.post<FeatureResponse>('/api/feature', data); return response.data; } catch (error) { throw new Error('Failed to process feature'); } };React 中的状态管理

使用钩子管理功能组件中的状态。

const FeatureComponent: React.FC = () => { const [input, setInput] = useState(''); const [message, setMessage] = useState(''); const handleSubmit = async (event: React.FormEvent) => { event.preventDefault(); try { const response = await processFeature({ input }); setMessage(response.message); } catch (error) { setMessage('Error processing feature'); } }; return ( <div> <form onSubmit={handleSubmit}> <input type="text" value={input} onChange={(e) => setInput(e.target.value)} /> <button type="submit">Submit</button> </form> {message && <p>{message}</p>} </div> );};

在我们的 .NET Core 项目中从 Redis 迁移到内存中缓存简化了我们的架构,并提高了特定用例的性能。这一旅程强化了结构良好的开发方法和现代编码实践的重要性。通过将 .NET Core 用于后端,将 TypeScript 用于前端,我们创建了一个可靠且可缩放的解决方案,可有效满足用户的需求。

如果你喜欢我的文章,请给我一个赞!谢谢

0 阅读:0

程序员有二十年

简介:感谢大家的关注