- 主题:请教一下dotnet的兼容性
我们公司一直用 ruby on rails 开发 web 应用,最近开始考虑技术转型。新的开发栈基本是前后端彻底分离,后端只提供 web api 就好了。我个人是比较倾向 c# 的,主要原因是用了 ts 之后回不去没类型的开发了,再加上跟 java 和 go 比还是更喜欢 c# 的语法,尤其是能重载运算符,这样做计算的时候代码更好读,另外 async/await 的语法也应该更容易上手。
但是在有人提出了反对意见,由于我对 c#、asp.net 的历史和生态也没啥概念,所以特地来请教一下。
首先的问题就是代码兼容性,现在 dotnet/asp.net 也是每年都发新版本。是否会存在不同版本间有大量的代码需要重写,或者由于第三方依赖迟迟升级不上去的情况存在?如果有的话,产生问题的原因更多是因为 c# 的语法 breaking change,还是基础库接口产生了变化,或者是 asp.net 的升级导致的?
其次就是关于 web service,大概看了看 benchmarks,似乎 asp.net core 的效率还挺不错的。我的问题是 asp.net 作为后端开发,如果只是提供 web api,或者 grpc 的话,会不会有点太重了,有没有轻量一些的替代品?它的启动时间、内存占用的情况如何?
另外这个问题可能会有点儿特别,我开发用的系统是 ubuntu。我猜最好用的 ide 应该大概率是自家的 vs for windows,不过还是想问一下,有人在 linux 上用 vscode 吗?用起来感觉如何,会不会是非常难用的一个状态?比如我个人的感觉,哪怕稍微改点儿 java 代码,我也宁可下个 intellij idea,而不会选在 vscode 里面凑合。
--
FROM 222.153.56.*
太感谢了,刚才回了一堆又没发出来,也许过几天会再出来……
总之我感觉有信心了
【 在 keygen 的大作中提到: 】
: 代码的兼容性:
: ...................
--
FROM 222.153.56.*
这两天试了一下,发现了几个小问题,不过都解决了
【 在 mingtong 的大作中提到: 】
: 你的这几个担心都不是问题。
: 代码兼容性:只有.net framework之间存在这个问题,net6往后都是做加法了,所以变化不会大。
: 性能:一个hello world的内存占用在20多m左右,运行时取决于你的gc模式,有激进的,也有保守的,可能会影响局部的benchmark。net6之后的minimal模式就是要给用户一个轻量级的startup模式,你可以用模版新建一个试一下
: ...................
--
FROM 203.184.25.*
目前感觉问题不大
唯一有问题的应用场景就是 aws lambda,冷启动时间实在是太感人了。相同的功能,如果用 node18 给 128M 内存,冷启动 950ms 返回结果。dotnet6 + 128M 大概 9s,如果把内存增加到256的话将近4s。
【 在 keygen 的大作中提到: 】
: 欢迎到时候一起讨论~
--
修改:eGust FROM 203.184.25.*
FROM 203.184.25.*
我的实现还是基于 web service,对 lambda 的 event 进行转发。本地启动服务的时候,也能感觉到不是马上就起来的,所以 web service 本身的初始化也是占用不少时间的。如果直接处理 lambda event,就能把这部分时间省下来,缺点是直接绑 aws 上了。这个目前来说我觉得不重要,我也就是大概试一下,有个概念而已。
这方面可能 node 还是有优势吧,另外一个用 rust 写的服务,冷启动也要 1s+ 才返回结果。不过做的事情不一样,不好直接比。基于 web service 的实现,本身服务的启动速度非常敏感。而对传统的 web 框架来说,服务启动的时间不敏感。我回头还得再试个 py,这样做对比的时候有数字说话。我们公司其他人都还处于在想象的阶段,真正用过 lambda 的没几个人
另外 java 也是这个月初刚获得了一个免费的技术升级,大幅提高冷启动的速度。个人认为理论上 .net 也大同小异,估计下一个就会得到优化了。
【 在 keygen 的大作中提到: 】
: 频繁 scale 波动,cold start的话,的确比较麻烦,比不上 aot 的和解析语言
: 据说 java 在 lambada 上更快点,不知道为什么,都是类似的处境
: 之前看文章有些人迁移到了 Container App,保留一个 instance 常驻来解决这个问题
: ...................
--
修改:eGust FROM 222.153.59.*
FROM 222.153.59.*
aws lambda 是基于极其轻量的 vm(基于 firecracker,据称只有5M的 overhead,启动速度也是毫秒级别)的服务,并不会保证有一个实例持续运行。超过一定时间没有访问的话,该 vm 就被干掉了。
serverless 就是这么一个概念,前端静态文件放 s3 上面,cloudfront 自带 cdn 功能,给个域名就行。api request 走的是 api gateway,相当于 load balancer,根据请求启动对应的 lambda。lambda 本身是有一个 handler 会接受到一个 event,里面带有一定格式的数据。所以实际上是没有服务进程的,只在使用的时候才会启动 vm 调用 handler。
比较流行的一种开发方式是,还是开发正常的 web service,完全可以单独部署。在它的基础之上,把 api gateway 发过来的 event 再转换成 http request,交给原有的逻辑处理,再把 http response 转换回 api gateway 能理解的格式。所以这个 web service 实际上并没有启动一个 tcp 服务,而是 handler 里让原本的服务处理一个 http request 就完了。
【 在 keygen 的大作中提到: 】
: 我感觉不是太理解你这个 web service 的定义
: 一般作为 web service,不是常驻一个服务端进程,一直处理传过来的 http request 吗?
:
: ...................
--
修改:eGust FROM 222.153.59.*
FROM 222.153.59.*
用 node 做示例的话,应用大概是这样的
// app.ts
import fastify from 'fastify';
export const app = fastify();
app.get('/foo', async () => { ... });
app.post('/bar', async () => { ... });
// standalone.ts
import { app } from './app';
const main = async () => {
await app.listen({ host: ..., port: ... });
};
main();
// index.ts
import awsLambdaFastify from '@fastify/aws-lambda';
import { app } from './app';
export const handler = awsLambdaFastify(app);
这样本地开发,或者部署成单独的 http server 的时候,用 standalone 来启动应用,这种情况下用不到 index.ts。反之 aws lambda 用的话,就不需要 standalone.ts,aws 会调用 index 里的 handler。
【 在 keygen 的大作中提到: 】
: 我感觉不是太理解你这个 web service 的定义
: 一般作为 web service,不是常驻一个服务端进程,一直处理传过来的 http request 吗?
:
: ...................
--
修改:eGust FROM 222.153.59.*
FROM 222.153.59.*
这些都是比较具体的问题了,我们公司生产环境能用上 container 还有很长一段路要走
如果是基于 k8s 的话那自然是没问题的
另外能做成 serverless 的服务相对来说应该比较独立,规模不至于太大,功能也不会太复杂,我觉得用什么语言问题不大
【 在 keygen 的大作中提到: 】
: 噢,你说的是 serverless
: 我们是传统的写个 service,让它一直跑。跑在自己 DC 类 k8s 集群上,实例在更新之前一直存在。
: lambda 如果保证比较稳定的输入量的话,一直 hot 着应该还好。或者自己写一个定时请求保活?
: ...................
--
FROM 203.184.25.*
java 当然也不是不可以,只不过我个人不太喜欢
【 在 jimmycmh 的大作中提到: 】
: 选型还得考虑招人的问题吧
: java工程师一抓一大把,c#不太好招
: 符
: ...................
--
FROM 203.184.25.*