【后端】【Java】可直接落地的 Nginx + Java(Spring Boot)+ Redis 的短链系统实现

一个 示例,包含:

  • 系统架构

  • Nginx 配置

  • Java 代码(短链生成 + 统计 + 302 跳转)

  • Redis 数据结构

  • 访问统计方案

这是一个完整、可部署的模板。


✔️ 1. 系统架构设计

复制代码
用户访问短链 → Nginx → Java短链服务 → Redis查真实链接
                              ↓
                        记录统计数据(异步)
                              ↓
                          302 重定向

✔️ 2. Redis 数据结构设计

1)短链映射

复制代码
Key: short:abcd123
Value: https://example.com/activity?channel=weibo

2)访问统计(可选)

复制代码
短链点击次数:count:abcd123 → incr
访问记录:log:abcd123 → list push {...json...}

✔️ 3. Nginx 配置(负责把短链路由给 Java)

短链域名:https://s.example.com/xxxxxx

nginx.conf

复制代码
server {
    listen 80;
    server_name s.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
    }
}

访问 s.example.com/abcd12 时会转到 Java 后端:

复制代码
GET http://127.0.0.1:8080/abcd12

✔️ 4. Java (Spring Boot) 实现示例

4.1 短链生成 API

Controller

复制代码
@RestController
@RequestMapping("/api")
public class ShortLinkController {

    @Autowired
    private ShortLinkService shortLinkService;

    @PostMapping("/shorten")
    public String createShortLink(@RequestParam String longUrl) {
        return shortLinkService.createShortUrl(longUrl);
    }
}

4.2 Service:短链生成 + 存入 Redis

复制代码
@Service
public class ShortLinkService {

    @Autowired
    private StringRedisTemplate redis;

    private static final String SHORT_KEY_PREFIX = "short:";

    public String createShortUrl(String longUrl) {
        // 生成短链 ID:6 位
        String shortId = RandomStringUtils.randomAlphanumeric(6);

        // 保存到 Redis
        redis.opsForValue().set(SHORT_KEY_PREFIX + shortId, longUrl);

        // 返回短链
        return "https://s.example.com/" + shortId;
    }
}

✔️ 5. Java Controller:接收短链并 302 跳转

关键部分:

  • 查 Redis

  • 记录统计

  • 返回 302

    @RestController
    public class RedirectController {

    复制代码
      @Autowired
      private StringRedisTemplate redis;
    
      @Autowired
      private AsyncLogService asyncLogService;
    
      private static final String SHORT_KEY_PREFIX = "short:";
    
      @GetMapping("/{shortId}")
      public ResponseEntity<Void> redirect(@PathVariable String shortId,
                                           HttpServletRequest request) {
          String key = SHORT_KEY_PREFIX + shortId;
          String longUrl = redis.opsForValue().get(key);
    
          if (longUrl == null) {
              return ResponseEntity.notFound().build();
          }
    
          // 异步记录访问
          asyncLogService.log(shortId, request);
    
          // 302 跳转
          HttpHeaders headers = new HttpHeaders();
          headers.setLocation(URI.create(longUrl));
          return new ResponseEntity<>(headers, HttpStatus.FOUND);
      }

    }


✔️ 6. 异步记录统计(可选)

通过 @Async 保存访问日志,不阻塞跳转。

异步记录点击数量 + 访问日志

复制代码
@Service
public class AsyncLogService {

    @Autowired
    private StringRedisTemplate redis;

    @Async
    public void log(String shortId, HttpServletRequest request) {
        String ua = request.getHeader("User-Agent");
        String ip = request.getRemoteAddr();
        long timestamp = System.currentTimeMillis() / 1000;

        // 点击次数
        redis.opsForValue().increment("count:" + shortId);

        // 访问日志
        JSONObject log = new JSONObject();
        log.put("ip", ip);
        log.put("ua", ua);
        log.put("time", timestamp);

        redis.opsForList().leftPush("log:" + shortId, log.toString());
    }
}

✔️ 7. 查询统计的 API 示例

查询访问次数

复制代码
@GetMapping("/api/count/{shortId}")
public Long getCount(@PathVariable String shortId) {
    return Long.valueOf(redis.opsForValue().get("count:" + shortId));
}

查询访问日志

复制代码
@GetMapping("/api/logs/{shortId}")
public List<String> getLogs(@PathVariable String shortId) {
    return redis.opsForList().range("log:" + shortId, 0, 100);
}

✔️ 8. 运行效果

  1. 创建短链:

    POST /api/shorten
    longUrl=https://example.com/page?channel=test

    返回:
    https://s.example.com/aB92kF

  2. 用户访问短链:

    GET https://s.example.com/aB92kF

  3. Java 读取 Redis → 记录统计 → 302 跳转

  4. 在后台看到统计数据:

    count:aB92kF = 1023
    log:aB92kF = [ {ip:..., ua:..., time:...}, ... ]


相关推荐
初次攀爬者8 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺8 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart10 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
闲云一鹤10 小时前
nginx 快速入门教程 - 写给前端的你
前端·nginx·前端工程化
NE_STOP11 小时前
MyBatis-mybatis入门与增删改查
java
孟陬14 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
想用offer打牌14 小时前
一站式了解四种限流算法
java·后端·go
华仔啊15 小时前
Java 开发千万别给布尔变量加 is 前缀!很容易背锅
java
也些宝15 小时前
Java单例模式:饿汉、懒汉、DCL三种实现及最佳实践
java