超强实用技巧:使用 ClickHouse 构建实时单页应用程序

图片

本文字数:14982;估计阅读时间:38 分钟

作者:Dale McDiarmid

本文在公众号【ClickHouseInc】首发

图片

简介

在构建实时应用程序时,常常需要向数据库发出大量并发请求,以填充页面的各个模块。为了防止在浏览器中暴露数据库凭证,通常会在数据库和客户端之间添加一个 Web 服务器。

尽管这种架构对于某些应用是必须的,但在构建单页应用、原型验证或需要快速迭代的演示时,这样的设置可能显得多余。开发者可以考虑采用“仅客户端”架构,让浏览器直接查询数据库。本文将重点介绍这种“仅客户端”架构的关键数据库考量。

单页应用(SPA)无需重新加载整个页面即可动态更新内容,所有渲染和逻辑都在客户端完成,旨在提供流畅的用户体验,非常适合这种架构。

我们将展示如何在确保数据库安全且避免因请求过多而导致过载的前提下,通过 ClickHouse 实现“仅客户端”应用。为此,我们将利用一些简单却强大的功能,并复用一些配置方案,只需少量 JavaScript,即可在几分钟内为现有应用程序安全添加分析功能。

我们已在多个公开演示中成功采用了这种“仅客户端”方法,包括 ClickPy、CryptoHouse 和 adsb.exposed 等 SPA 应用。不过,我们也理解某些用户需要更高的安全性,并希望通过添加 API 层来减少攻击面。为此,ClickHouse Cloud 提供了查询端点(Query Endpoints)。

背景与传统架构

传统的 Web 应用程序多采用客户端-服务器架构,前端通过 API 与后端服务器交互,后端则负责与数据库的通信。

图片

在这种架构中,开发人员需要构建和维护复杂的后端系统,增加了开发过程的复杂性,延长了迭代周期。此架构的普及主要是为了应对前端直接访问数据库带来的安全问题,因为将数据库直接暴露于公共互联网存在较高风险,因此需要通过安全的 API 通信来加以防护。然而,这种架构的复杂性也会带来更多扩展性方面的挑战——后端服务器需要精细管理和手动调整才能有效应对增长。这使得开发和维护 Web 应用程序的过程变得资源密集且效率较低。

图片

近年来,越来越多的应用开始允许客户端代码直接在浏览器中访问数据库。这一 Web 应用构建方式由 Firebase 推广,尤其是其 Firebase Realtime Database 引入了基于浏览器的访问模式,通过令牌(包括匿名身份验证令牌)管理安全规则。

Firebase 在以前端为驱动的开发社区中广受欢迎,确立了这一实践,其他服务(如 Supabase)也将其应用于 PostgreSQL 数据库。此方法减少了复杂的后端需求,使开发过程更简单,并提升了迭代速度,同时将扩展性交由数据库管理,简化了应用的扩展性设计。

不过,这些数据库服务通常为事务型工作负载优化,适合处理应用状态,但不适合用于大数据集的分析和可视化。幸运的是,通过简单配置,ClickHouse 也可以在此架构中高效部署。

以下是希望在 ClickHouse 中采用仅客户端架构的用户的配置建议。对于希望简化体验的用户,我们推荐使用 ClickHouse Cloud 的查询端点(Query Endpoints),它可以大大降低复杂性,并通过可配置的 REST 端点提供 ClickHouse 快速的分析查询功能。

单页应用中集成 ClickHouse

ClickHouse 拥有多项关键功能,使其能够在仅客户端架构中高效运行:

  • HTTP 接口与 REST API:支持通过 JavaScript 直接使用 SQL 查询 ClickHouse,默认监听端口 8123 或 8443(SSL 版本),后者在 ClickHouse Cloud 中开放。该接口支持 HTTP 压缩与会话管理。

  • 输出格式:提供超过 70 种输出格式,包括 20 种 JSON 子格式,便于 JavaScript 解析。

  • 查询参数:支持查询模板化,并增强了对 SQL 注入的防护。

  • 基于角色的访问控制:管理员可以限制对特定表和行的访问权限。

  • 查询复杂性限制:可将用户权限设为只读,并限制查询复杂度及可用资源。

  • 配额:限制特定客户端的查询次数,防止恶意客户端导致数据库负载过高。

例如,以下代码展示了如何从 ClickPy 实例查询过去 30 天下载次数最多的 Python 包。此处使用 play 用户并添加 FORMAT JSONEachRow 参数(默认为 TabSeparated),以返回格式化的 JSON 数据。

echo 'SELECT project, sum(count) as c FROM pypi.pypi_downloads GROUP BY project ORDER BY c DESC LIMIT 3 FORMAT JSONEachRow' | curl -u play: 'https://clickpy-clickhouse.clickhouse.com' --data-binary @-

{"project":"boto3","c":"27234697969"}
{"project":"urllib3","c":"17015345004"}
{"project":"botocore","c":"15812406924"}

尽管这些功能为从浏览器查询 ClickHouse 提供了基本支持,但在将实例暴露于公共互联网时,需要经过细致的配置和管理。

在这些最佳实践中,我们主要关注读取请求。这类请求通常是仅客户端的公开应用中唯一适合的请求类型。同时,我们假设所有客户端(即用户)使用相同的用户名发出查询。不过,这些原则也可以扩展至多个 ClickHouse 用户。

仅允许 HTTPS 连接

对于面向公众的应用程序,应用中用于大多数查询的用户凭证会显示在浏览器中,任何开发人员都可以通过查看网络请求轻松获取。虽然这些凭证通常不属于敏感信息,但应用程序可能允许用户修改查询所用的用户名和密码。这些凭证应通过安全连接(HTTPS)进行保护和传输。有关为开源 ClickHouse 配置 TLS 和开放 HTTPS 接口的具体方法,请点击此处查看【https://clickhouse.com/docs/en/guides/sre/configuring-ssl】。

例如,在类似 ClickHouse play 环境的应用中,用户创建账户后可以修改其用户名和密码。这些用户可能享有更高权限或配额。

ClickHouse Cloud 仅在 8443 端口上提供安全的 HTTP 接口。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值