]]>后记,应该是http请求体限制,上传不了原图,bug+1,自己手动压缩了一下
当时我也有创建过微信公众号,b站账号,想要也搞搞自己的“自媒体”,不过哪有那么容易,而已我又是一个很木讷的人,写不出什么东西,更拍不出什么东西,后面都一个个废弃了。
博客也写了两年多了,打算把之前创建的微信公众号重新找回使用,流量什么的无所谓了。因为最初也不知道写什么,大概率就是我博客的一个国内渠道了,也蛮好,这样我博客也不用处理国内访问慢的问题了。
然后就是这样,谨以此文记录
忘了,最后贴一个二维码,有兴趣的可以关注下
]]>考虑的机型分别是索尼的a6400和zve10,看参数都差不多,只是在功能和操作上有区别,对于一个摄影新手来说,我不太懂那些快捷键取景器啥的,就买了这个相对比较好看的zve10,而且还便宜了一点。第一次买这类产品,图安心就在官网买了,贵是贵了点,还送了个《孤独摇滚》联动的肩带,我很喜欢。
然后就是一顿的摸索,在我写这个博文的时候,已经是晚上12点多了
然后是简单拍的一些照片(图片还得压缩一下再上传,烦)
感觉是要比我现在手机(小米11ultra)有质感一点,不过清晰度上面并没有取胜
简单的对比,有水印的是手机
相机原厂的套头,还是难为它了,长焦还是打不过手机的5倍
ok,收拾收拾睡觉,希望我不是因为一时头热,后面房租交了有闲钱打算整个定焦头玩玩。
]]>之前有过几次,别人说我看起来想起个高中生一样,不知道是不是因为我的穿搭,一个普通单色的外套,背着个电脑包,然后留着平头,貌似程序员好多类似的模样,估计都是懒得折腾。
我本人看起来应该不是显年轻,皮肤比较黑,脸上也比较粗糙,也不知道为啥会被这么觉得,可能还有不善言辞所表现出的羞涩,看起来不像个年龄多大的(我本身也没多大,只是肯定不是高中就是了)。
想起我高中的时候,我应该算班里比较“老成”的了,那时候胡子就蛮长了,加上整天熬夜,胡子也不怎么干净,脸上痘痘啥呀,声音也比较鸭子桑,所以在同学中算是很显“老”的,记得之前舍友还让我模仿他长辈给他请假呢,不过后面放弃了。
最后回到这个话题,我也是感觉自己从来没有过成年一样,长辈还是长辈一样对你,弟弟妹妹呀,还是那个弟弟妹妹,一切仿佛都没怎么变过,所以也从未感觉到自己长大,只不过是从之前的上班变成了上学,从讨厌读书变成了讨厌加班,还有就是多了来自亲戚的催婚,身边的朋友也渐渐疏远。
什么时候感觉到成年了呢,我觉得就是获得了更多的“尊重”的时候吧,父母开始更多的询问你的意见,来自银行和销售的一句句先生,熟人的含嘘问暖等,自己终于不再是社会的小透明,不需要通过哭喊来表达自己的意见,当然,我对这些“尊重”并不感冒。
]]>在刚才浅浅的体验了一两个小时来看,缺点就是穿透的地址最长只能保持30天,我自费购买的内网穿透,地址可以一直保留的,然后就是境外的地址可能会有延迟,白天这一小段时间我感觉还行 ;
优点嘛,还是很多的,首先就是免费,然后带宽有足足20mb/s,比向日葵不知道高到哪里去了,境外带宽果然就像不要钱一样。
微软的相关地址 https://learn.microsoft.com/zh-cn/azure/developer/dev-tunnels/
安装
winget install Microsoft.devtunnel# mac: brew install --cask devtunnel# linux: curl -sL https://aka.ms/DevTunnelCliInstall | bash
登录
devtunnel user login# 可以微软或github账号登录
创建临时隧道
devtunnel host -p 8080 -a# -a 为开启匿名访问# 执行后会输出外网地址
上面为创建一个临时隧道,关闭后下次再执行,又是一个新地址,你也可以创建一个非临时,实现地址复用,最长30天
流程:创建隧道
devtunnel create -a#-a 表示可以表示隧道可以匿名访问#执行成功会输出隧道信息
给上面创建的隧道加上端口
devtunnel port create [隧道名] -p 8080#隧道名为可选,默认为刚才创建的隧道#可以添加多个端口
开启隧道
devtunnel host [隧道名]#隧道名为可选,默认为刚才创建的隧道
devtunnel delete [隧道名]
可以删除隧道
在网页访问的时候,会显示一个防钓鱼页面,你需要点击同意,这个在http post等方法或者请求头不是text/html这种请求时,不会显示,所以不会影响前段实际的接口请求
名称 | 限制 |
---|---|
流量(Bandwidth ) | 5 GB 每用户 |
隧道数 | 10 每用户 |
活动连接 | 20 每端口 |
端口数 | 10 每个隧道 |
http请求速率 | 1500/min 每端口 |
速率 | 最高 20 MB/s 每隧道 |
最大http请求体大小 | 16 MB |
上述限制每月重置
]]>最后,他好像还有sdk,可以嵌入到自己程序里,比如开发环境创建隧道,后面再看看
然后,最近花得最多的事情,就是调整自己的情绪了,别人是借酒消愁,我是借着饮料提神。
总感觉干了好多,又心里空落落的。
前几天打算注册一个个体工商户,自己折腾一些玩具感觉没啥意思,想做点实际的东西,即使没有市场,也算是发展一下副业吧。
自己在手机上申请了,感觉流程还蛮简单,按照表单的要求填写就行了;不过后面没通过,我是用房东的住宅申请的,有些营业范围不支持,还有名称有要求,审核员也给我说了哪些的问题,应该怎么改,不过营业范围还是没记清楚,后面打算再去市监局问问。
上年还是全程处于蛮紧张的状态的,前年是很迷茫,两个还蛮相似的;
今年就是目标就是准备我的个体户,做几个自己的产品,然后重新考虑自己的职业生涯,还有就是我的这个博客吧,上年没有写什么实质上我觉得有内容的博文,今年争取多发挥发挥吧,好好梳理自己。
下年此刻见!
]]>更换方法也很简单,可以使用 certbot,几个命令就搞定了,官方文档很完善。之前配置了证书的已经过期了的,可以自动给你切换,不需要做任何事,证书快到期的话,会自动更新。新增域名的话,重新运行下命令,然后选择要添加https的域名就行。
]]>名词介绍
J2ME:
上面的j2me模拟器大多不能直接运行,还需要个jvm,这才是我头疼的地方,移植jvm到嵌入式设备太头疼了。
MRP:
其他
下面说下折腾的过程,起因是我上年买了个开源掌机,叫miyoo mini
,长下面这样,还蛮精致的
自带了FC、GB、GBA、MD,PS等模拟器,不过既然是开源掌机,肯定是折腾了,上面一些平台可能是一些人的童年,对于我的童年来说,当年的山寨机才是。
之前写了个pc运行j2me的教程 就想着能不能移植到这个上面
直接流水账式的说下我的过程
1. java也有arm版,就想能不能直接复制到机子的sd卡上运行 -> 成功
2. 运行awt界面-> 失败,因为这个机子只有SDL,不支持 x11界面,所以不能显示界面
3. 那换个思路,github上看到了个JavaFrameBuffer的库,可以直接向framebuffer写数据;
先在自己电脑上测试了下,可以,然后交叉编译复制到机子上,运行,也成功
然后画一些图形试试,其他都成功了
但是显示文字失败了;
Fontconfig error: Cannot load default config fileFontconfig error: Cannot load default config fileException in thread "Test" java.lang.Error: Probable fatal error:No fonts found.
4. 试了网上很多方法,比如复制字体,创建配置文件,都不行,也去瞅了好久java相关源码,真的头大,最后放弃。
可能是这个机子上没fontconfig的问题把,期间还看了一些其他jvm,想着换个简单的jvm,源码简单些,我把底层改了不就行了吗,结果还是我想多了,参考上面我提到的几个jvm,我都尝试过移植,一是要准备一堆环境,二是我还要上班,断断续续的经常中断
5. 后面陆陆续续想起这件事,也找找一些解决方案,
上面最后的尝试,后面有空再看吧,另外最近在折腾doppio
这个jvm,把j2me
跑在网页上应该比跑在嵌入式上简单一点吧,所以最近会优先折腾这个,毕竟网页版也好调试,那个机子我每次调试都是复制程序过去,然后再把sd卡拔出来看日志文件,太费事了。
最后,那个mrp平台是无意间想到了,毕竟是和java同期的产品,而且在我的映像中,这玩意的稳定要比java还好点,java则有很多兼容性问题,不知道是不是当时山寨厂商的问题,或者mrp作为一个国内平台技术支持完善点。
未完待续...
]]>最近在准备自考,虽然我也感觉这玩意没啥用,主要现在我也不知道干什么,总要找点事情干,就当是一个备用选择吧。
然后就是再看《人间失格》这本书,回顾了下电视剧《仙剑1》,也快追完了,打算看完之后把之前攒的游戏经量都通关几个,算是今年最大的任务了吧
写这个文章,主要是刚好想起上年年底的一个规划,觉得今年就是玩玩就好,但还是陷入了所谓的焦虑之中,整天想着一些提升却没什么头绪,只会让自己玩没玩好,学也没学啥。所以今年到年底这些时间,希望我们调整好自己的思绪。
然后就是因为公司业务的整改,导致了暂时的降薪,说是暂时,也是因为老板是这么说而已,不知道什么时候恢复,以及今年的年终奖怎么样,我不想他们那些大厂裁员的,没有那么厚的家底,我觉得影响还蛮大的。还有就是来到公司两年,我也没没提涨薪,可能是因为最近的大环境,老板也没提,所以今年年底,我决定提一下这个问题,实在不行,就下年另寻出路了。
为什么是下年呢,又涉及了我想说的另外一个问题,因为是今年买了车,贷款分了两年,等到下年年终,我的车贷也就差不多了,剩下的就算失业也不至于负担不起。买车呢,主要是觉得自己生活太单一了,觉得有车后多转转也能改变一下什么,还有就是上年的疫情放开,我觉得下年会比较适合出去玩玩。现实是,我的想法错了,当然我觉得也不是神多大的错。我觉得今年的环境会变好,实际变得更差了,这让我深深感觉到自己意识的不足,所以股票这种东西,还是别乱碰,没有足够的知识,只是在赌,这是我根据我的这件事学到的或者做出的结论吧。
还有就是买车年还是蛮新奇的,幻想着之后有车的生活,买完车跑了大半年后呢,就觉得没啥用了,好像没车也没啥,还多花了前,要是存着的话,我今年就可以稍微躺平些了。其实想想吧,还是有用的,可能就是人太贪心,拥有了就不在乎了,还是一个心态的问题,也是我上面说的,应该改变一下心态。
不早了,就先写到这里了,可能有些错别字,我也不想检查了。
感谢看到这里的陌生人,希望我的一些负面情绪不会给你造成什么困惑,我想,未来的某一天,我会更了解我自己。
]]>接着是太湖,相比那些人造,我还是更喜欢这些偏自然一点的景观,不过由于错过了一些观景平台,晚上有些地方没开,所以就没找到好点观景点
回去快到南京的时候,下了特别大的雨,还好我们刚到服务区,不过雨中的感觉真是惬意呀
后面再出去玩的话,就多记录点吧
]]>通过编译运行这个lol私服,我觉得lol的架构设计还是蛮有意思的。
首先,你登陆账号然后匹配的那个界面是使用了类似于'浏览器套壳'的方式写的,至少马服是这样的。这样的好处就是lol大厅的特效还蛮多,而且很灵活,直播什么的都可以塞进去,最关键的是因为灵活,所以每个国家的界面都可以深度定制,这是lol和其他游戏非常不一样的一点。
然后就是真正的游戏客户端,也就是你选择英雄后启动的那个才是真正的游戏客户端。
这里总的说一下逻辑
大厅管理好友,活动,商城,已经选择英雄匹配等,都是在这里,这里和游戏真正的逻辑都是没关系的,真正的逻辑在于在于游戏开始时,启动器拉起客户端,传递游戏服务器的ip和用户的token,用户凭token连接到服务器,拉取对局信息和游戏地址等信息。而游戏模式,应该是在服务器的,也就是说什么无限火力还是大乱斗,都是服务器应用了不同的逻辑脚本而已,和客户端无关,客户端仅展示动画音效,和传递用户的操作。
github项目地址 https://github.com/LeagueSandbox/GameServer
就先说到这吧,我先折腾折腾,最后放一下游戏的截图
]]>具体上一次记录是三个月前了,平时我都是在自己的飞书的账号上写一些东西,有些我觉得对别人或者对别人理解我有意义的才会写到博客。
最近的三个月,好像也没干什么事,公司上,什么都没怎么搞。自考,挂了,后面打算还是报班吧。倒是和朋友一起出去玩了蛮多地方,自己也逛了蛮多地方,收获嘛,可能就是一片焦虑。
不知道怎么形容,就是感觉自己的时间很紧张的样子,而自己平时下班,却又什么都提不起兴趣,上班不知道做啥,只是这种深夜emo的时候,在想着自己要立什么什么志向。然后这个帖子就当是立一个flag吧,希望我下次再写博客的时候,可以改变这件事。
今天的年初的时候,我还立了一个今年计划,不过没有写在博客,说的就是我要把我现在的游戏都通关,现在一个还没玩呢。哈哈。
然后自己最近也跟着他们内卷,写了一个ai镜像站,最近一段时间,应该就是忙这个玩意吧。地址在这里: https://ai.nekogeek.com/chat
最近刷到的一个视频,感觉和我的情况特别像,我想,我应该改变点什么,后面有什么再写吧,睡了
]]>今天早上看我的rss的时候,发现访问不了,就去看了下服务器,这下好了,服务器ssh也登不了了,于是只能去腾讯云的后台看看了。
这是刚才的截图了,中间服务器的监控了停了一段时间。用了自带的一键登录。
到后台发现是 halo
直接占满了 cpu
,虽然我这机子性能的确不高吧,感觉也没啥人访问呀
下次再遇到这种情况,再去仔细看下吧
]]>更新软件源
sudo apt update
安装vsftpd
sudo apt install vsftpd
安装成功后应该默认建立了一个 ftp用户,
使用下面命令可以查看
sudo cat /etc/passwd | grep ftp#输出下面的代表有个ftp用户#ftp:x:117:123:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin
开始配置相关数据
Ubuntu防火墙相关
查看系统的防火墙
sudo ufw status#输出 inactive表示防火墙关闭,active表示防火墙开始状态
如果防火墙是启动状态,按照下面步骤添加防火墙配置,关闭状态则无视
#添加规则sudo ufw allow 20,21,990/tcpsudo ufw allow 40000:50000/tcp
添加ftp用户
#ftptest为用户名,请换成你自己的用户名sudo adduser ftptest#后面会让你输入密码和其他信息,这些都不重要,随便输入
现在在home下应该有个 ftptest的文件夹,为创建的用户主目录
配置ftp访问
#打开配置文件,这里使用nanosudo nano /etc/vsftpd.conf
你将看到vsftp的配置文件
下面几个必要的配置
listen=NO
这个保持关闭
local_enable=YES
是否允许本地用户登录,本地用户也就是我们上面增加的用户,所以一定为YES
write_enable=YES
是否允许写入,也就是ftp上传之类的,这个看具体情况
allow_writeable_chroot=YES
vsftp默认允许用户主目录可写,设置了上面的需要同时设置这个
chroot_local_user=YES
是否限定用户在主目录内,不限制的话用户可以回退查看系统的其他目录,为了安全为YES
pasv_min_port=40000
pasv_max_port=50000
这是两个配置,指定被动模式的端口范围,注意端口不要被防火墙拦截
重启服务应用配置
sudo systemctl restart vsftpd
停用ftp
#关闭服务sudo service vsftpd stop#禁用开机自启sudo systemctl disable vsftpd.service
注意关闭对应端口,虽然不关也没啥问题
相关参考
]]>解决问题的方法也很简单,执行操作的时候直接返回,然任务后台执行就好了,但是这样用户就没法知道任务具体有没有执行成功之类的了,操作回馈不够及时,当前也可以把当前任务的执行进度放到redis中,通过另外一个接口来轮询进度。
每个类似的业务逻辑都写上这样一套逻辑显然是有很多冗余的,所以我就自己写了异步任务工具类,用于处理这种类似的情况。
先说下大体的架构
示例代码
@Slf4jpublic class AsyncTaskManager { private static final ThreadLocal<AsyncTask<?>> CURRENT_TASK = new ThreadLocal<>(); /** * 异步操作任务调度线程池 */ private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(10); private static <T> String createAsyncTask(String name, Callable<T> callable) { return createAsyncTask(name, true, callable); } /** * 创建一个异步任务 * * @param name 任务名称 * @param extendsSession 是否继承会话信息 * @param callable 任务执行方法, * @param <T> 任务返回值,可以为空 * @return 任务id, 后续用户这个id获取任务相关信息 */ private static <T> String createAsyncTask(String name, boolean extendsSession, Callable<T> callable) { CommonAssert.isNotNullOrEmpty(name, "任务名称不能为空"); if (CURRENT_TASK.get() != null) { throw new BusinessException("无法在异步任务中创建嵌套的异步任务,请换用AsyncManager"); } String id = UUID.fastUUID().toString(); AsyncTask<T> task = new AsyncTask<>(id, name, extendsSession, callable); EXECUTOR.execute(task); return id; } /** * 更新任务进度 * * @param current 当前进度 * @param total 总任务 */ public static void updateProcess(Double current, Double total) { AsyncTask<?> task = CURRENT_TASK.get(); if (task != null) { task.updateProcess(current, total); } else { log.warn("当前不在异步任务中,无法调用此方法,at:" + getCallerInfo()); } } /** * 记录日志到前端显示 * * @param message 消息模板 * @param args 模板参数 */ public static void log(String message, Object... args) { AsyncTask<?> task = CURRENT_TASK.get(); if (task != null) { task.log(message, args); } else { log.warn("当前不在异步任务中,无法调用此方法,at:" + getCallerInfo()); } } public static void message(String message, Object... args) { AsyncTask<?> task = CURRENT_TASK.get(); if (task != null) { task.setMessage(message, args); } else { log.warn("当前不在异步任务中,无法调用此方法,at:" + getCallerInfo()); } } /** * 注册当前异步任务 */ public static void registerTaskInfo(AsyncTask<?> task) { if (CURRENT_TASK.get() != null) { throw new BusinessException("当前异步任务已存在"); } CURRENT_TASK.set(task); } /** * 清除当前异步任务 */ public static void clearTaskInfo() { CURRENT_TASK.remove(); } /** * 当前方法调用者相关信息 */ private static String getCallerInfo() { StackTraceElement trace = new Throwable().getStackTrace()[2]; return trace.getClassName() + "." + trace.getMethodName() + ":" + trace.getLineNumber(); }
@Slf4jpublic class AsyncTask<T> implements Runnable { private static final String PROCESS_STATUS_WAITING = "WAITING"; private static final String PROCESS_STATUS_RUNNING = "RUNNING"; private static final String PROCESS_STATUS_SUCCESS = "SUCCESS"; private static final String PROCESS_STATUS_ERROR = "ERROR"; private final RedisCache redisCache = SpringUtils.getBean(RedisCache.class); private final AsyncProcessInfo<T> asyncProcessInfo; private final String redisKey; private final String threadName; private final Callable<T> callable; private SecurityManager securityManager = null; private Subject subject = null; public AsyncTask(String id, String name, boolean extendsSession, Callable<T> callable) { log.info("开始创建异步任务,id:{},name:{},extendsSession:{}", id, name, extendsSession); this.asyncProcessInfo = new AsyncProcessInfo<T>(); this.asyncProcessInfo.setCreateTime(new Date()); this.asyncProcessInfo.setId(id); this.asyncProcessInfo.setName(name); this.asyncProcessInfo.setStatus(PROCESS_STATUS_WAITING); this.threadName = "async-task-|" + Thread.currentThread().getName() + "|-" + name + "-" + IdUtils.fastUUID().substring(0, 3); this.redisKey = CacheConstants.CacheKeys.SYSTEM_ASYNC_TASK_INFO + CacheConstants.CACHE_KEY_SEPARATOR + id; this.callable = callable; if (extendsSession) { try { //处理shiro相关的问题 securityManager = SecurityUtils.getSecurityManager(); subject = SecurityUtils.getSubject(); } catch (Exception e) { throw new RuntimeException("当前线程不存在有效的会话", e); } } this.writeToRedis(); } public AsyncProcessInfo<T> getAsyncProcessInfo() { return asyncProcessInfo; } private void writeErrorTosRedis(String errorInfo) { log.error("异步任务执行异常,id:{},name:{}", asyncProcessInfo.getId(), asyncProcessInfo.getName()); asyncProcessInfo.setStatus(PROCESS_STATUS_ERROR); asyncProcessInfo.setMessage(StringUtils.isEmpty(errorInfo) ? "异步任务执行异常" : errorInfo); redisCache.setCacheObject(redisKey, asyncProcessInfo, 10, TimeUnit.MINUTES); } private void writeToRedis() { log.info("开始更新异步任务状态:id:{},name:{}", asyncProcessInfo.getId(), asyncProcessInfo.getName()); this.checkInterrupted(); redisCache.setCacheObject(redisKey, asyncProcessInfo); } /** * 检查当前线程是否收到了终止命令 */ private void checkInterrupted() { if (Thread.interrupted()) { writeErrorTosRedis("异步任务被终止"); throw new RuntimeException("异步任务被终止"); } } /** * 更新任务进度 * * @param current 当前进度 * @param total 总任务 */ public void updateProcess(Double current, Double total) { this.checkInterrupted(); asyncProcessInfo.setTotal(total); asyncProcessInfo.setCurrent(current); writeToRedis(); } /** * 记录日志到前端显示 * * @param message 消息模板 * @param args 模板参数 */ public void log(String message, Object... args) { this.checkInterrupted(); if (asyncProcessInfo.getLogs() == null) { asyncProcessInfo.setLogs(new ArrayList<>()); } asyncProcessInfo.getLogs().add(StringUtils.format(message, args)); writeToRedis(); } /** * 设置提示消息 */ public void setMessage(String message, Object... args) { this.checkInterrupted(); asyncProcessInfo.setMessage(StringUtils.format(message, args)); writeToRedis(); } @Override public void run() { try { log.info("开始执行异步任务,id:{},name:{}", asyncProcessInfo.getId(), asyncProcessInfo.getName()); AsyncTaskManager.registerTaskInfo(this); Thread.currentThread().setName(threadName); asyncProcessInfo.setExecuteTime(new Date()); asyncProcessInfo.setStatus(PROCESS_STATUS_RUNNING); writeToRedis(); //继承会话设置 if (securityManager != null && subject != null) { ThreadContext.bind(securityManager); ThreadContext.bind(subject); } else { //不继承会话就关闭数据权限 DataScopeManager.disableDataScope(); } T result = this.callable.call(); log.info("异步任务执行结束,id:{},name:{}", asyncProcessInfo.getId(), asyncProcessInfo.getName()); asyncProcessInfo.setResult(result); asyncProcessInfo.setStatus(PROCESS_STATUS_SUCCESS); redisCache.setCacheObject(redisKey, asyncProcessInfo, 10, TimeUnit.MINUTES); } catch (Exception e) { writeErrorTosRedis(e.getMessage()); } finally { //清理数据 ThreadContext.remove(); ActionLogUtil.clean(); PageHelper.clearPage(); DataScopeManager.clearDataScope(); AsyncTaskManager.clearTaskInfo(); } }}
public class AsyncProcessInfo<T> { /** * 任务的uuid */ private String id; /** * 任务名称 */ private String name; /** * 任务创建时间 */ private Date createTime; /** * 任务执行时间 */ private Date executeTime; /** * 导出任务状态 * WAITING * RUNNING * SUCCESS * ERROR */ private String status; /** * 任务总进度 */ private Double total; /** * 任务当前执行进度 */ private Double current; /** * 任务执行结果 */ private T result; /** * 执行结果是个文件的情况下下载文件(暂时没用到) */ private Boolean downloadMode = false; /** * 任务执行日志 */ private List<String> logs; /** * 任务消息 */ private String message;}
其中有个shiro相关的代码,不需要可以忽略
当在需要异步任务的时候,直接调用 AsyncTaskManager.createAsyncTask 返回一个id给前端,前端再根据id去轮询任务进度。前端的这部分,也可以直接封装成一个组件
]]>左上角服务中即可找到 s3
开通服务后在 s3
的管理界面新建储存桶,如果不用作图床之类,建议阻止公开访问
之后可以在这个储存桶里管理和上传文件
如果需要第三方 api 访问的话,需要生成一对访问密钥
在右上角的个人设置界面。(当初找了好久,不像腾讯云那种,直接储存桶管理界面就可以看到访问密钥和url)
![JQRTPDCE4QGMPJWTK.png](https://thetbw-hk.cos.thetbw.xyz/blog/HJ%7BQ%7BRTPD%7DCE4QGM(PJW(TK_1669605929567.png)
后续补充,安全起见,建议使用services -> IAM 中新建个子用户,只赋予s3的访问权限
随后使用访问密钥就可以使用 aws的sdk访问服务了
贴一下java sdk的代码,其他的大同小异吧
public void upload() { S3Client client = S3Client.builder() .region(Region.AP_SOUTHEAST_1) //选择一个服务区域,注意选cn应该是要aws中国账号 .credentialsProvider(() -> new AwsCredentials() { @Override public String accessKeyId() { return "密钥id"; } @Override public String secretAccessKey() { return "密钥"; } }).build(); PutObjectRequest putObjectRequest = PutObjectRequest.builder() .bucket("储存桶名称") .key("test/test.png") .build(); PutObjectResponse response = client.putObject(putObjectRequest, FileSystems.getDefault().getPath("C:\\Users\\thetbw\\test.png")); System.out.println(response.toString()); client.close(); }
如果使用其他程序,例如 cloudreve
这种网盘,绑定 aws s3
,应该还需要一个访问 url,可以在这里找到可用的url,选择离你区域近的即可,或者搜索 aws endpoints
,可以找到aws的相关文档。
比如我用的就是 https://s3-accesspoint.ap-southeast-1.amazonaws.com/