Lindorm Serverless + CQL + Springboot,快速搭建弹性Web服务

简介: 本文主要介绍如何通过阿里云云原生数据库Serverless服务,快速基于SpringBoot构建一个用户管理系统。

背景

作为面向大数据场景的半结构化、结构化存储系统,Lindorm已经在阿里发展了近十年,并始终保持着快速的能力更新和技术升级,是目前支撑阿里经济体业务的核心数据库产品之一。其在功能、性能、稳定性等方面的诸多创新历经了长时间的大规模实践考验,被全面应用于阿里集团、蚂蚁集团、菜鸟、大文娱等各个业务板块,成为目前为止公司内部数据体量最大、覆盖业务最广的数据库产品。

Lindorm Serverless 支持按需计费,弹性扩展,最大限度的降低了用户使用门槛,运维难度和容量规划操作。Lindorm CQL完全兼容了cassandra社区的Query Language,提供了类SQL的查询能力,可以非常快速的结合spring等框架,帮助业务逻辑快速开发。本文以一个简单的用户管理系统为例子,介绍如何给予Lindorm快速构建一个web服务,这个系列后续也会介绍更多复杂的使用方式。

前期准备工作

公有云用户
在阿里云首页搜索Lindorm,进入Lindorm管理控制台购买Lindorm Serverless集群,可以根据需求选择包年包月或者按量付费。
1.png
2.png

已经有集群版实例子的同学可以跳过这个步骤。

购买成功之后,实例列表就包含了一个LindormServerless类型的实例在实例管理页面找到连接信息页面,开通公网访问,获取集群链接串。
3.png

链接信息中默认都存在"CQL连接",默认的链接地址是包括了VPC环境下的地址和端口,也可以执行公网开放功能获取公网地址和端口。Lindorm使用CQL访问都是走认证的,默认用户名和默认密码在用户控制台可以看到,通过该地方获取的用户名和密码可以访问走CQL访问Lindorm。
4.png

至此Lindorm的集群的购买工作就已经完成了。

了解Cqlsh
执行建表和KeySpace操作用户可以通过cqlsh访问lindorm serverless,操作方式请参考cqlsh使用指南。

下载到CQLSH的代码后,可以通过如下命令访问Shell

./cqlsh $host $port -u $username -p $password

其中host指的是CQL链接串中:9042之前的部分,port不填写默认为9042

创建namespace和table

cqlsh> CREATE KEYSPACE test_keyspace WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}  AND durable_writes = true;
cqlsh> use test_keyspace;
cqlsh:test_keyspace> CREATE TABLE user (id BIGINT , username text,  age int, password text, PRIMARY KEY (id)) ;

对应的CQL表结构
CREATE TABLE test_keyspace.user (   
id bigint PRIMARY KEY,   
username text,   
age int, 
password text);

生成SpringBoot项目

在开始实际编码之前,建议先阅读下官方文档,了解Spring Data for Cassandra项目

在Spring模版生成器中生成项目模版,所需配置如下图:
5.png

生成出来的项目下载后导入进Idea,大概如下
6.png

现在我们就拥有了一个完整spring on cql,接下来的工作就是完善代码构造一个用户管理页面啦。

构造用户管理页面

定义域模型(实体类)
本文主要针对单个用户主键场景,所有的读写操作都是针对主键ID来执行,注意主键需要标注PrimaryKey。用户ID作为主键是全局唯一的,重复写入一个用户ID会发生覆盖。

/*
 * Copyright Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.lindorm.cqldemo.entity;
import org.springframework.data.cassandra.core.mapping.CassandraType;
import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;
@Table(value = "user")
public class UserTable {
    @PrimaryKey
    @CassandraType(type = CassandraType.Name.BIGINT)
    private long id;
    private String username;
    private String password;
    private int age;
    public long getId() {
        return id;
    }
    public UserTable setId(long id) {
        this.id = id;
        return this;
    }
    public String getUserName() {
        return username;
    }
    public UserTable setUserName(String username) {
        this.username = username;
        return this;
    }
    public String getPassword() {
        return password;
    }
    public UserTable setPassword(String password) {
        this.password = password;
        return this;
    }
    public int getAge() {
        return age;
    }
    public UserTable setAge(int age) {
        this.age = age;
        return this;
    }
}

定义spring-data接口
这里主要继承了CrudRepository,包括了比较常见的增删改查

 * Copyright Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.lindorm.cqldemo.entity;
package com.alibaba.lindorm.cqldemo.repository;
import com.alibaba.lindorm.cqldemo.entity.UserTable;import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<UserTable, Long> {
    UserTable findById(long id);
    void deleteById(Long id);
}

CrudRepository的接口定义如下

public interface CrudRepository<T, ID> extends Repository<T, ID> {
  <S extends T> S save(S var1);
  <S extends T> Iterable<S> saveAll(Iterable<S> var1);
  Optional<T> findById(ID var1);
  boolean existsById(ID var1);
  Iterable<T> findAll();
  Iterable<T> findAllById(Iterable<ID> var1);
  long count();
  void deleteById(ID var1);
  void delete(T var1);
  void deleteAll(Iterable<? extends T> var1);
  void deleteAll();
}

定义service
咱们这个简单的demo代码支持拿到用户列表,写入用户信息,更新用户信息,删除用户等基本功能,其支持的基本功能如图。

/*
 * Copyright Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.lindorm.cqldemo.service;
import com.alibaba.lindorm.cqldemo.entity.UserTable;
import java.util.List;
public interface UserService {
    public List<UserTable> getUserList();
    public UserTable findUserById(long id);
    public void save(UserTable userTable);
    public void edit(UserTable userTable);
    public void delete(long id);
}
/*
 * Copyright Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.lindorm.cqldemo.service;
import com.alibaba.lindorm.cqldemo.entity.UserTable;
import com.alibaba.lindorm.cqldemo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Override
    public List<UserTable> getUserList() {
        List<UserTable> userList = new ArrayList<>();
        for (UserTable table : userRepository.findAll()) {
            userList.add(table);
        }
        return userList;
    }
    @Override
    public UserTable findUserById(long id) {
        return userRepository.findById(id);
    }
    @Override
    public void save(UserTable userTable) {
        userRepository.save(userTable);
    }
    @Override
    public void edit(UserTable userTable) {
        userRepository.save(userTable);
    }
    @Override
    public void delete(long id) {
        userRepository.deleteById(id);
    }
}
 

完成webcontroller
UserController实现基本的跳转功能,将咱们的前段页面跟service关联起来。

 * Copyright Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.lindorm.cqldemo.web;
import com.alibaba.lindorm.cqldemo.entity.UserTable;
import com.alibaba.lindorm.cqldemo.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import java.util.List;
@Controller
public class UserController {
    @Resource UserService userService;
    @RequestMapping("/")
    public String index() {
        return "redirect:/list";
    }
    @RequestMapping("/list")
    public String list(Model model) {
        List<UserTable> userTables = userService.getUserList();
        model.addAttribute("userTables", userTables);
        return "user/list";
    }
    @RequestMapping("/toAdd")
    public String toAdd() {
        return "user/userAdd";
    }
    @RequestMapping("/add")
    public String add(UserTable userTable) {
        userService.save(userTable);
        return "redirect:/list";
    }
    @RequestMapping("/toEdit")
    public String toEdit(Model model,Long id) {
        UserTable userTable = userService.findUserById(id);
        model.addAttribute("userTable", userTable);
        return "user/userEdit";
    }
    @RequestMapping("/edit")
    public String edit(UserTable userTable) {
        userService.edit(userTable);
        return "redirect:/list";
    }
    @RequestMapping("/delete")
    public String delete(Long id) {
        userService.delete(id);
        return "redirect:/list";
    }
}

完成前端页面
前端页面的具体代码,请参考具体的示例代码。总共实现了3个页面,list.html负责用户展示,userAdd.html负责用户添加,userEdit.html负责用户更新页面。

完成main函数

 * Copyright Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.lindorm.cql.springdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class CqlDemoApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(CqlDemoApplication.class);
    }
    public static void main(String[] args) throws Exception {
        System.out.println(System.getProperty("java.class.path"));
        SpringApplication.run(CqlDemoApplication.class, args);
    }
}

增加cassandra链接参数
通过继承AbstractCassandraConfiguration来指定链接的EndPoint,用户名,密码等信息。用户名密码可以通过阿里云管控系统或者Afanty上获取。

 * Copyright Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.lindorm.cqldemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.config.CqlSessionFactoryBean;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;
@Configuration
@EnableCassandraRepositories
public class CassandraConfig extends AbstractCassandraConfiguration {
  private String hostList = "ld-bp1r9jd815x6y8w4d-proxy-lindorm-pub.lindorm.rds.aliyuncs.com";
  private String keyspaceName = "test_keyspace";
    //需要填写自己集群的对应账号
  private String userName = "xxx";
    //需要填写自己集群的对应密码
  private String password = "xxx";
  @Override
  protected String getLocalDataCenter() {
    return "datacenter1";
  }
  protected String getContactPoints() {
    return hostList;
  }
  public String getKeyspaceName() {
    return keyspaceName;
  }
  @Override
  public CqlSessionFactoryBean cassandraSession() {
    CqlSessionFactoryBean cqlSessionFactoryBean = super.cassandraSession();
    cqlSessionFactoryBean.setPassword(password);
    cqlSessionFactoryBean.setUsername(userName);
    return cqlSessionFactoryBean;
  }
}

当然,你也可以通过更改application.properties调整cassandra参数,需要注意contact-points, username,password这几个参数是必须填写的,详细的参数请参考spring-cassandra的官方文档。

启动查看

执行main函数,如果一切符合的预期的话,我们的webserver已经可以正常拉起,可以在本机localhost:8080端口访问这个简易的用户管理系统。
7.png

我们可以测试添加一个新的用户3,也可以修改删除和删除某个用户,一个拥有最基础的功能的用户管理系统就已经完成啦!
8.png

增加css修饰网页
我们的页面还没有经过任何修饰,感觉很粗糙,在resources/static/css目录加入bootstrap.css文件,修饰下我们的网页,使我们的网页变得更加美观!
9.png

更多高级功能

本文只涉及了单一主键场景下基于主键进行增删改查的简单例子。实际上spring + cql + lindorm serverless还可以支持更加强大的能力,比如复合主键,二级索引,多维索引等。想了解更多如何关于Lindorm的能力,请参考Lindorm使用文档 https://help.aliyun.com/product/172543.html?spm=5176.15155444.J_5253785160.4.28925d80aDpnwq。 也请期待本文的姊妹篇,springboot + lindorm构建用户账单系统,我们会更加详尽的介绍如何设计复合主键,二级索引等能力。

Have fun with the demo!

DEMO地址:https://yisu-emr-test.oss-cn-hangzhou.aliyuncs.com/cqldemosimple.tar.gz?Expires=1607326773&OSSAccessKeyId=TMP.3KiP9R7i9DAuKNBj819jEy4eGDUXkmP6VRftrYKvRvgFvChWLYtEjirTNXExELzg7M8at6w2YaK3EaFxSJfyq45mc2rM2v&Signature=KGJoI5QvXUd4ob4k2%2BTbl8u8EME%3D&versionId=CAEQGhiBgMC52YrOsRciIDBkYzIyMTM3ZjUzZjQyZGQ4ZDkzM2VjZTNmNjZmYmJk&response-content-type=application%2Foctet-stream

相关实践学习
【玩转ComfyUI】基于函数计算一键部署AI生图平台ComfyUI
本次实验将带大家通过使用阿里云产品函数计算FC,快速使用ComfyUI实现更高质量的图像生成。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
存储 Serverless 数据库
科普文:云计算服务类型IaaS, PaaS, SaaS, BaaS, Faas说明
本文介绍了云计算服务的几种主要类型,包括IaaS(基础设施即服务)、PaaS(平台即服务)、SaaS(软件即服务)、BaaS(后端即服务)和FaaS(函数即服务)。每种服务模式提供了不同的服务层次和功能,从基础设施的提供到应用的开发和运行,再到软件的交付使用,满足了企业和个人用户在不同场景下的需求。文章详细阐述了每种服务模式的特点、优势和缺点,并列举了相应的示例。云计算服务的发展始于21世纪初,随着互联网技术的普及,这些服务模式不断演进,为企业和个人带来了高效、灵活的解决方案。然而,使用这些服务时也需要注意服务的稳定性、数据安全性和成本等问题。
15180 5
|
Serverless Python
借助 serverless 将 MCP 服务部署到云端
本文介绍了如何将 MCP 服务通过 SSE 协议部署到云端,避免本地下载和启动的麻烦。首先,使用 Python 实现了一个基于 FastMCP 的网络搜索工具,并通过设置 `transport='sse'` 启用 SSE 协议。接着,编写客户端代码测试服务功能,确保其正常运行。随后,利用阿里云函数计算服务(FC 3.0)以 Serverless 方式部署该服务,包括创建函数、配置环境变量、添加依赖层以及部署代码。最后,提供了客户端测试方法和日志排查技巧,并展示了如何在不同工具(如 Cherry-Studio、Cline 和 Cursor)中配置云端 MCP 服务。
2191 11
借助 serverless 将 MCP 服务部署到云端
|
Cloud Native 安全 Serverless
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。
|
弹性计算 人工智能 自然语言处理
魔搭社区与函数计算:高效部署开源大模型的文本生成服务体验
在数字化时代,人工智能技术迅速发展,开源大模型成为重要成果。魔搭社区(ModelScope)作为开源大模型的聚集地,结合阿里云函数计算,提供了一种高效、便捷的部署方式。通过按需付费和弹性伸缩,开发者可以快速部署和使用大模型,享受云计算的便利。本文介绍了魔搭社区与函数计算的结合使用体验,包括环境准备、部署应用、体验使用和资源清理等步骤,并提出了改进建议。
|
机器学习/深度学习 监控 物联网
函数即服务(FaaS)
函数即服务(FaaS)
1068 6
|
消息中间件 关系型数据库 Serverless
【阿里云】一键部署创建函数计算服务以处理多媒体文件
通过阿里云的一键部署功能,轻松创建函数计算服务以处理多媒体文件。首先选择地域并配置资源栈名称及其他必要参数,如登录凭证、实例类型及数据库配置。过程中可能需开通相关服务如消息服务MNS,并确保账户有足够的余额。完成配置后,系统自动创建资源栈。当状态显示“创建成功”即部署完毕。最后,通过提供的URL及凭据访问应用,上传PPTX文件进行处理,并下载处理后的结果。
405 5
|
Kubernetes 安全 Serverless
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
Kubernetes 的架构问题之Serverless Container中提供对外服务如何解决
362 6
|
Java Serverless Docker
函数计算产品使用问题之使用Docker镜像部署的Web服务如何获取客户端的真实IP
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
417 9
|
存储 运维 安全
函数计算产品使用问题之如何获取到访问其他阿里云服务所需的AccessKey、SecretKey或STS Token
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。

热门文章

最新文章

相关产品

  • 函数计算