前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在 Spring Boot REST API中使用Json Web Token

在 Spring Boot REST API中使用Json Web Token

作者头像
用户4235284
发布于 2023-10-14 07:59:00
发布于 2023-10-14 07:59:00
49000
代码可运行
举报
文章被收录于专栏:后端学习之道后端学习之道
运行总次数:0
代码可运行

在本文中,我将展示如何进行基于 Spring Boot 的 REST API进行鉴权。保护 REST API 以避免对公共 API 进行任何不必要的调用已成为一种趋势。我们将使用一些 Spring 引导功能来实现 Spring 安全,并使用 JSON WebTokens 进行授权。

这种情况下的用户流是

  1. 用户登录
  2. 我们验证用户凭据
  3. 令牌被发送回用户代理。
  4. 用户尝试访问受保护的资源。
  5. 用户在访问受保护资源时发送 JWT。我们验证 JWT。
  6. 如果 JWT 有效,我们允许用户访问该资源。

JSON WebTokens,称为 JWT,用于为用户形成授权。这有助于我们构建安全的 API,而且易于扩展。在身份验证期间,返回一个 JSON Web 令牌。每当用户想要访问受保护的资源时,浏览器都必须在 Authorization 标头中随请求一起发送 JWT。这里要了解的一件事是保护 REST API 是一种很好的安全实践。

基本上,我们将展示

  1. 验证 JSON WebToken
  2. 验证签名
  3. 检查客户端权限

前置准备

基于 Spring Boot 的 REST API

我将为我在这篇博文中创建的公司保护 REST API  。此 API 还包括缓存。用户将尝试访问/cachedemo/v1/companies/并且由于 API 受到保护,他将得到如下响应:

现在我们将实现如何保护这个 API 以及在它被保护时如何访问它。

添加用户和用户注册

由于我们要为 API 添加授权,因此我们需要用户能够登录和发送凭据的位置。这些凭证将被验证并生成一个令牌。然后,此令牌将在对 API 调用的请求中传输。令牌将在我们将添加的 Spring 安全授权过滤器中进行验证。如果令牌有效,用户将能够访问 API。

创建用户模型
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.betterjavacode.models;

import javax.persistence.*;
import java.io.Serializable;

@Entity(name = "User")
@Table(name = "user")
public class User implements Serializable
{
    public User()
    {

    }

    @Id
    @GeneratedValue(strategy =  GenerationType.IDENTITY)
    private long id;

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    public long getId()
    {
        return id;
    }

    public void setId(long id)
    {
        this.id = id;
    }

    public String getUsername()
    {
        return username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }
}

我们将添加一个控制器,用户可以在其中注册 和 的详细username 信息password

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.betterjavacode.resources;

import com.betterjavacode.models.User;
import com.betterjavacode.repositories.UserRepository;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/cachedemo/v1/users")
public class UserController
{
    private UserRepository userRepository;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public UserController(UserRepository userRepository, BCryptPasswordEncoder bCryptPasswordEncoder)
    {
        this.userRepository = userRepository;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
    }

    @PostMapping("/signup")
    public void signUp(@RequestBody User user)
    {
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        userRepository.save(user);
    }

}

现在当我们向 POST 请求时/cachedemo/v1/users/signup,一个用户将被保存在数据库中。Password因为我们正在使用,所以用户将以加密格式保存BCryptPasswordEncoder。我们将展示用户如何登录以创建令牌。

用户登录

为了处理用户登录,我们将添加一个AuthenticationFilter 将添加到 FilterChain 中的,Spring boot 将适当地处理它的执行。该过滤器将如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.betterjavacode.SpringAppCache;


import com.fasterxml.jackson.databind.ObjectMapper;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;

public class AuthenticationFilter extends UsernamePasswordAuthenticationFilter
{
    private AuthenticationManager authenticationManager;

    public AuthenticationFilter(AuthenticationManager authenticationManager)
    {
        this.authenticationManager = authenticationManager;
        setFilterProcessesUrl("/login");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException
    {
        try
        {
            com.betterjavacode.models.User creds = new ObjectMapper().readValue(request.getInputStream(), com.betterjavacode .models.User.class);
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(creds.getUsername(), creds.getPassword(),new ArrayList<>()));
        }
        catch(IOException e)
        {
            throw new RuntimeException("Could not read request" + e);
        }
    }

    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain, Authentication authentication)
    {
        String token = Jwts.builder()
                .setSubject(((User) authentication.getPrincipal()).getUsername())
                .setExpiration(new Date(System.currentTimeMillis() + 864_000_000))
                .signWith(SignatureAlgorithm.HS512, "SecretKeyToGenJWTs".getBytes())
                .compact();
        response.addHeader("Authorization","Bearer " + token);
    }
}

基本上,用户将在请求中向以 /login 结尾的 URL 发送凭据。此过滤器将有助于对用户进行身份验证,如果身份验证成功,将在响应标头中添加一个带有授权密钥的令牌。

令牌验证和授权

我们添加另一个过滤器 AuthorizationFilter 来验证我们之前通过 AuthenticationFilter 传递的令牌。该过滤器将如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.betterjavacode.SpringAppCache;

import io.jsonwebtoken.Jwts;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;


public class AuthorizationFilter extends BasicAuthenticationFilter
{
    public AuthorizationFilter(AuthenticationManager authenticationManager)
    {
        super(authenticationManager);
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException, ServletException
    {
        String header = request.getHeader("Authorization");
        if(header == null || !header.startsWith("Bearer"))
        {
            filterChain.doFilter(request,response);
            return;
        }

        UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request,response);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request)
    {
        String token = request.getHeader("Authorization");
        if(token != null)
        {
            String user = Jwts.parser().setSigningKey("SecretKeyToGenJWTs".getBytes())
                    .parseClaimsJws(token.replace("Bearer",""))
                    .getBody()
                    .getSubject();
            if(user != null)
            {
                return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
            }
            return null;
        }
        return null;
    }
}

如果令牌验证成功,则返回用户并将其分配给安全上下文。

为了启用 Spring 安全性,我们将添加一个带有注释的新类 WebSecurityConfiguration @EnableWebSecurity。这个类将扩展标准WebSecurityConfigurerAdapter。在这个类中,我们将限制我们的 API 并添加一些我们需要在没有任何授权令牌的情况下访问的白名单 URL。这将如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.betterjavacode.SpringAppCache;

import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter
{
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    private UserDetailsService userDetailsService;

    private static final String[] AUTH_WHITELIST = {
            "/v2/api-docs",
            "/swagger-resources",
            "/swagger-resources/**",
            "/configuration/ui",
            "/configuration/security",
            "/swagger-ui.html",
            "/webjars/**"
    };

    public WebSecurityConfiguration(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder)
    {
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
        this.userDetailsService = userDetailsService;
    }


    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        httpSecurity.cors().and().csrf().disable().authorizeRequests()
                .antMatchers(AUTH_WHITELIST).permitAll()
                .antMatchers(HttpMethod.POST, "/cachedemo/v1/users/signup").permitAll()
                .anyRequest().authenticated()
                .and().addFilter(new AuthenticationFilter(authenticationManager()))
                .addFilter(new AuthorizationFilter(authenticationManager()))
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception
    {
        authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource()
    {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**",new CorsConfiguration().applyPermitDefaultValues());
        return source;
    }
}

在方法配置中,我们限制了大多数 API,只允许 Swagger URL 和注册 URL。我们还向 HttpSecurity 添加过滤器。我们将添加自己的UserDetailsServiceImpl 类来验证用户凭据。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.betterjavacode.services;

import com.betterjavacode.models.User;
import com.betterjavacode.repositories.UserRepository;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.Collections;

@Component
public class UserDetailsServiceImpl implements UserDetailsService
{
    private UserRepository userRepository;

    public UserDetailsServiceImpl(UserRepository userRepository)
    {
        this.userRepository = userRepository;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
    {
        User user = userRepository.findByUsername(username);
        if(user == null)
        {
            throw new UsernameNotFoundException(username);
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), Collections.emptyList());
    }
}
演示

完成所有代码更改后,现在我们已准备好创建用户、登录和访问受保护的 REST API。从上图中,用户在访问受保护的 API 时收到拒绝访问错误。为了演示这个,我已经用用户名test1和密码 test@123 注册了一个用户。

登录的 POST 请求将为我们提供授权令牌作为响应。现在在我们的 GET 请求中使用此令牌来检索公司数据。此 GET 请求如下所示:

通过这种方式,我们展示了如何使用 JSON 网络令牌保护 REST API。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
cloudwego/eino v0.3.29全新登场!关键特性详解,构建更稳健的子图抽取和智能提示新时代
在现代分布式系统和微服务架构中,图结构数据的高效管理和分析始终是技术团队头疼的问题。cloudwego团队旗下的eino项目自诞生以来,凭借出色的性能和丰富的功能,成为众多开发者构建复杂系统的得力助手。今天,我们迎来了v0.3.29版本的重大更新。本期文章,我们将深度解析此次版本新增的两大核心特性:“支持子图抽取的中断错误处理”(extract sub graph interrupt error)和“默认提示中新增保证运行信息”(ensure run info to default prompt),带你全面了解这些改进将如何提升系统稳定性和用户体验。
福大大架构师每日一题
2025/05/10
790
cloudwego/eino v0.3.29全新登场!关键特性详解,构建更稳健的子图抽取和智能提示新时代
eino v0.3.31正式上线!三大核心更新助你打造更高效智能系统
2025年5月12日,国内领先的高性能微服务框架CloudWeGo旗下智能工具编排库eino发布最新版本v0.3.31!本次更新带来了触发图回调机制完善、工具节点顺序执行能力升级以及字段映射类型检查的优化,助力开发者实现更灵活、高效、稳健的微服务治理。本文将为你解读这三个关键更新背后的技术亮点、实战价值与应用示例,全面提升你的开发效率和系统质量。
福大大架构师每日一题
2025/05/14
600
eino v0.3.31正式上线!三大核心更新助你打造更高效智能系统
eino v0.3.34来了!新增WithEagerExecution,性能与易用性再升级!
在当今云计算与高并发时代,对高性能、高扩展性的服务框架需求日益增长。CloudWeGo团队旗下的轻量级Go语言RPC框架——eino,以其极简设计和强大性能,一直深受开发者喜爱。近日,eino发布了0.3.34版本,带来了备受期待的新特性——WithEagerExecution,再一次提升了框架的易用性与执行效率。
福大大架构师每日一题
2025/05/21
1030
eino v0.3.34来了!新增WithEagerExecution,性能与易用性再升级!
eino v0.3.35 全新发布!支持多内容格式,性能与灵活性全面升级
2025年5月20日,云原生开源项目 eino[1] 发布了 v0.3.35 版本!本次更新聚焦于增强内容格式支持,提升开发灵活性和易用性,由社区贡献者 @meguminnnnnnnnn 发起并完成。作为 CloudWeGo 生态中备受关注的高性能日志库,eino 的每一次迭代都在助力开发者打造更加高效、可靠的微服务。
福大大架构师每日一题
2025/05/22
810
eino v0.3.35 全新发布!支持多内容格式,性能与灵活性全面升级
Go语言开发AI智能体有多丝滑?字节重磅开源Eino框架,内含保姆级教程
开发基于大模型的软件应用,就像指挥一支足球队:组件是能力各异的队员,编排是灵活多变的战术,数据是流转的足球。
机器之心
2025/02/05
8900
Go语言开发AI智能体有多丝滑?字节重磅开源Eino框架,内含保姆级教程
eino v0.3.36震撼发布 | 深度解读三大核心亮点,助力高效流式数据处理!
伴随着2025年5月21日的春风,云原生高性能Go框架EINO迎来了全新的v0.3.36版本更新。本次版本不仅修复了重要缺陷,更是在流处理与枚举标签解析功能上实现了功能性突破,显著提升了开发体验与运行效率。本文将全面解读本次版本的三大核心升级,为你的项目开发与性能优化带来实际价值。
福大大架构师每日一题
2025/05/23
1320
eino v0.3.36震撼发布 | 深度解读三大核心亮点,助力高效流式数据处理!
hertz v0.10.0 重磅发布!全新SSE支持、请求竞态检测与协议优化,开启更高效的云端微服务新时代!
2025年5月15日,云原生高速HTTP框架——Hertz迎来了重要里程碑版本v0.10.0。本次版本不仅带来了多项核心特性更新,更在协议支持、传输性能和服务稳定性方面做出了关键突破。作为一款广受欢迎的高性能Go语言网络框架,Hertz每一次升级都会引领云端微服务架构的发展潮流。
福大大架构师每日一题
2025/05/17
1030
hertz v0.10.0 重磅发布!全新SSE支持、请求竞态检测与协议优化,开启更高效的云端微服务新时代!
2021年大数据Flink(九):Flink原理初探
它扮演的是集群管理者的角色,负责调度任务、协调 checkpoints、协调故障恢复、收集 Job 的状态信息,并管理 Flink 集群中的从节点 TaskManager。
Lansonli
2021/10/11
1.2K0
深入浅出总结Flink运行时架构
Flink 运行时架构主要包括四个不同的组件,它们会在运行流处理应用程序时协同工作:作业管理器(JobManager)、资源管理器(ResourceManager)、任务管理器(TaskManager),以及分发器(Dispatcher)。因为 Flink 是用 Java 和 Scala 实现的,所以所有组件都会运行在Java 虚拟机上。接下来对各个组件的功能进行简单介绍i。
百思不得小赵
2022/12/01
6880
深入浅出总结Flink运行时架构
Flink(一)
Apache Flink(德语:快速灵巧,原德国柏林大学基金会项目)是一个框架和分布式处理引擎,用于对无界和有界数据流进行状态计算。ms级别水平。data flow+event sequence。
matt
2022/10/25
6210
Flink(一)
LLVM v20.1.4正式发布!全新升级、强劲性能助力编译新时代
LLVM(Low Level Virtual Machine)作为当今最重要的开源编译器基础设施项目之一,凭借其模块化设计、高度优化的编译技术与强大的跨平台支持,持续引领编译器生态的演进。2024年最新版本——LLVM v20.1.4已正式发布,带来了诸多改进与修复。今天,我们将深度剖析这个新版本的更新细节,并提供实用的安装和使用建议,助您轻松掌握LLVM最新技术趋势。
福大大架构师每日一题
2025/05/10
550
LLVM v20.1.4正式发布!全新升级、强劲性能助力编译新时代
cloudwego/netpoll v0.7.0 性能再升级:优化错误成本、增强 Runner 配置!
📢 最新动态 CloudWeGo 开源的高性能网络库 Netpoll 迎来 v0.7.0 版本更新!本次更新聚焦 性能优化、配置统一、GoPool 支持,并修复了多处细节问题,助力开发者构建更高效的网络应用!
福大大架构师每日一题
2025/04/02
800
cloudwego/netpoll v0.7.0 性能再升级:优化错误成本、增强 Runner 配置!
JavaScript性能优化
内存为什么需要管理呢?当程序执行的时候需要去内存申请一片空间进行使用,如果内存不进行管理释放内存空间,那么内存很容易就会溢出。
用户3045442
2020/08/12
1.2K0
JavaScript性能优化
DeepSpeed v0.16.9重磅发布!解锁全新性能优化与多项关键功能,深度解析升级亮点与技术革新
作为大规模分布式深度学习训练框架的领先者,DeepSpeed持续为AI研发者带来卓越的性能提升和强大功能支持。2025年5月23日,DeepSpeed正式发布v0.16.9版本,此次更新不仅修复了多个关键问题,还引入了多项重要优化和新特性,进一步提升了训练效率和系统稳定性。
福大大架构师每日一题
2025/05/25
1120
DeepSpeed v0.16.9重磅发布!解锁全新性能优化与多项关键功能,深度解析升级亮点与技术革新
kitex v0.13.1 正式发布:修复 gRPC 死锁隐患,FastPB 性能优化一览
微服务框架 Kitex 作为 CloudWeGo 开源生态的核心组件,近期发布了 v0.13.1 版本!本次更新虽是小版本迭代,却包含两项关键修复:FastPB 文件截断问题和 gRPC HTTP2 流清理死锁风险,直接影响高并发场景下的稳定性和性能。
福大大架构师每日一题
2025/04/10
880
kitex v0.13.1 正式发布:修复 gRPC 死锁隐患,FastPB 性能优化一览
快收藏!优化 Apache Flink 应用程序的 7 个技巧!
在 Shopify 中,我们将Apache Flink作为标准的有状态流媒体引擎,为我们的BFCM Live Map等各种用例提供支持。我们的 Flink 应用程序部署在利用Google Kubernetes Engine的 Kubernetes 环境中。我们的集群采用配置使用高可用性模式,配置任务管理为故障点。我们还为我们使用状态保存器作为我们使用的检查点和点写入谷歌云存储(GCS)。
从大数据到人工智能
2022/09/16
1.6K0
快收藏!优化 Apache Flink 应用程序的 7 个技巧!
重磅发布!cloudwego/kitex v0.13.0 来袭:性能优化、StreamX重构、gRPC调试神器上线!
CloudWeGo 社区正式发布 Kitex v0.13.0!本次更新聚焦 性能优化、协议兼容性提升、StreamX 接口重构,并新增多项实用功能,如 gRPC 连接状态诊断、Thrift 编解码优化,同时修复了内存泄漏等关键问题。无论是微服务开发者还是云原生爱好者,都不容错过!
福大大架构师每日一题
2025/04/04
350
重磅发布!cloudwego/kitex v0.13.0 来袭:性能优化、StreamX重构、gRPC调试神器上线!
tRPC智能体生态又升级:发布A2A协议的实现trpc-a2a-go
代码已开源至 GitHub:https://github.com/trpc-group/trpc-a2a-go
腾讯开源
2025/04/20
2920
tRPC智能体生态又升级:发布A2A协议的实现trpc-a2a-go
字节跳动微服务架构下的高性能优化实践
2019 年,字节跳动服务框架组针对大规模微服务架构下遇到的功能和性能痛点,以及吸收历史上旧框架下积累的经验与教训,着手开发了 RPC 框架 Kitex 以及周边一系列相关基础库,并在 2021 年正式在 Github 上开源。
深度学习与Python
2023/09/08
8480
字节跳动微服务架构下的高性能优化实践
Web前端性能优化工具
可以查看到网站所有资源的请求情况,包括加载时间、尺寸大小、优先级设置及HTTP缓存触发情况等信息,从而帮助我们发现可能由于未进行有效压缩而导致资源尺寸过大的问题,或者未合理配置缓存策略导致二次请求加载时间过长的问题等
yeedomliu
2022/12/03
1.1K0
Web前端性能优化工具
推荐阅读
cloudwego/eino v0.3.29全新登场!关键特性详解,构建更稳健的子图抽取和智能提示新时代
790
eino v0.3.31正式上线!三大核心更新助你打造更高效智能系统
600
eino v0.3.34来了!新增WithEagerExecution,性能与易用性再升级!
1030
eino v0.3.35 全新发布!支持多内容格式,性能与灵活性全面升级
810
Go语言开发AI智能体有多丝滑?字节重磅开源Eino框架,内含保姆级教程
8900
eino v0.3.36震撼发布 | 深度解读三大核心亮点,助力高效流式数据处理!
1320
hertz v0.10.0 重磅发布!全新SSE支持、请求竞态检测与协议优化,开启更高效的云端微服务新时代!
1030
2021年大数据Flink(九):Flink原理初探
1.2K0
深入浅出总结Flink运行时架构
6880
Flink(一)
6210
LLVM v20.1.4正式发布!全新升级、强劲性能助力编译新时代
550
cloudwego/netpoll v0.7.0 性能再升级:优化错误成本、增强 Runner 配置!
800
JavaScript性能优化
1.2K0
DeepSpeed v0.16.9重磅发布!解锁全新性能优化与多项关键功能,深度解析升级亮点与技术革新
1120
kitex v0.13.1 正式发布:修复 gRPC 死锁隐患,FastPB 性能优化一览
880
快收藏!优化 Apache Flink 应用程序的 7 个技巧!
1.6K0
重磅发布!cloudwego/kitex v0.13.0 来袭:性能优化、StreamX重构、gRPC调试神器上线!
350
tRPC智能体生态又升级:发布A2A协议的实现trpc-a2a-go
2920
字节跳动微服务架构下的高性能优化实践
8480
Web前端性能优化工具
1.1K0
相关推荐
cloudwego/eino v0.3.29全新登场!关键特性详解,构建更稳健的子图抽取和智能提示新时代
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档