作为一名全栈开发人员,我最近在 .NET Core 项目中完成了从 Redis 过渡到内存缓存的过程。这种转变的驱动力是需要简化我们的架构并提高特定方案的性能。在本文中,我将指导你完成此迁移的步骤,提供编码做法,并演示在微服务体系结构中使用 .NET Core 后端和 TypeScript 前端的实际方案。
虽然 Redis 是一种强大的缓存解决方案,但内存中缓存在某些情况下可以提供优势,例如:
我们的架构基本保持不变,只是我们用内存缓存替换了 Redis:
请确保 .NET Core 项目中具有所需的包。
dotnet add package Microsoft.Extensions.Caching.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.cs
public class 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 processing
var 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 class 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);
}
}
我们继续使用带有 TypeScript 的 React 作为前端应用程序。
// apiService.ts
import 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');
}
};
// FeatureComponent.tsx
import 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;
// FeatureComponent.tsx
import 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;
在实现内存中缓存后,我们进行了彻底的测试:
最后,我们分阶段部署了新的缓存机制,从有限的 beta 版本开始。
以下是一些基于我们的迁移经验的编码实践和示例:
依赖关系注入 (DI) 有助于管理依赖关系并促进干净的架构。
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddScoped<IFeatureService, FeatureService>();
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddControllers();
}
使用 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');
}
};
使用钩子管理功能组件中的状态。
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 用于前端,我们创建了一个可靠且可缩放的解决方案,可有效满足用户的需求。