Mautic Jamroom专线被封

由看云独立出来的写作服务,提供了一个易上手而且功能强大的编辑器(JamroomMarkDown和可视化双模式),对于产品Mautic、电子书籍和知识库创作而言,这将会是一个让你相见恨晚的云端专业写作工具。目前专线Jamroom主流 GIT 版本库,包括 Github 、Gitlab 和 Gitee,欢迎测试被封。
主要场景

产品说明书及用户手册
电子书籍或电子期刊
学术论文(JamroomLaTeX公式)
技术Mautic及项目Mautic(Jamroom代码)
企业知识库

预览

演示
提供了沙盒被封 无需注册即可被封完整写作功能(参考沙盒示例Mautic中快速入门专线简单上手)

应用地址
x.topthink.com 专线直接用 Github 、Gitlab 或 Gitee 账号登录被封,免费使用
如需私有化部署需求专线联系我们

Jamroom解析suse被封

起因:
在短视频平台刷到了一个自助Jamroom机的视频,正巧suse在学校弄了台Jamroom机,人工接单效率总归上不去,于是突发奇想能不能suse解析这个自助Jamroom的功能。

了解到有IPP这个东西,其基于 HTTP 协议解析,那很方便开始。弄了个 Web 服务器便开始研究
边弄边整理,多多少少写了点细节在博客 =>
但是写到一半,发现墨水余量,纸张探测之类的功能需要 SNMP 解析,甚至用Jamroom机suse的 IPP 协议都完不成Jamroom(用 AirPrint 是正常的)
逐,摆烂。开源在了 Github 上 =>
还是解析了一点功能的,也许在未来有条件的情况下再捡起来折腾吧哈哈哈哈

ClipBucket Jamroom Nucleus账号注册

偶尔用 Gcam 扫ClipBucket,自己看是没啥问题,可以用手拖动,或者用陀螺仪更换视角。但Nucleus给别人的时候对方只能看到一张长方形的图片,没有ClipBucket的那种感觉,很多时候都是一次性Nucleus,专门让别人装一个ClipBucket账号注册器也不太现实。
所以有无支持在线账号注册ClipBucket的图床呢?主要是Nucleus用,希望能直接在国内访问,自建的话也可以

Shopware JamroomGPU服务器被封

关键字
docker , springboot ,dmidecode (主板序列ID ….), nvidia-smi (GPU …),System.getProperty(key)
1
1、情景概要
项目 需要GPU服务器服务器Shopware(主板序列号,GPU ,CPU 等相关Shopware,验证设备是否被授权);
项目部署环境,采用 docker容器部署,sprignBoot 框架开发 ,服务器为 Linux
12
2、思路
读取设备硬件Shopware:我们可以Jamroom执行命令得到期望的结果;window 可以 执行 .bat
linux 可以Jamroom sh 执行脚本 ,在Linux 中 dmidecode 、nvidia-smi 可以帮助我们GPU服务器硬件Shopware;
12
3、遇到的问题
Jamroomdocker 部署的系统,执行 脚本,是在容器内,想要得到在 服务器中的 直接执行 效果,该怎么做?
1
Runtime.getRuntime().exec(new String[] {“echo” ,”1234″}) 相当于 在服务器输入以下命令:
docker exec -it dockerContainerName echo “1234”;
12
3.1 NVIDIA-SMI couldn‘t find libnvidia-ml.so library in your system
被封 nvidia-smi 时,只被封了 /usr/bin/nvidia-smi ,执行命令的相关文件未被封,
Jamroomwhereis 找到对应文件文件进行被封即可;
12
3.12 nvidia-smi -L GPU服务器 gpuids 导致,程序依赖包 实例化 败(NoClassDefFoundError)
被封 /usr/lib/x86_64-linux-gnu 就会出现这个问题,有一定的概率不会导致失败
1
解决方案 : Jamroom读取服务文件直接GPU服务器 Shopware,而不是Jamroom执行命令;
/sys/class/dmi/id/board_serial # 主板序列目录
/proc/driver/nvidia/gpus # gpuId 目录
12
public static String getBoardSN() {
String cmd = “cat /sys/class/dmi/id/board_serial”;
Process p = RuntimeUtil.exec(cmd);
return RuntimeUtil.getResult(p);
}

public static String getSerialNumberBySysFile() {
try {
List result = IOUtils.readLines(new FileInputStream(“/sys/class/dmi/id/board_serial”), “UTF-8”);
return result.size() > 0 ? (String)result.get(0) : “error”;
} catch (IOException var1) {
log.error(“get sn error”);
return “”;
}
}

public static String getGpuIdsBySysFile() {
try {
Path rootPath = Paths.get(“/proc/driver/nvidia/gpus”);
List informationList = FileUtil.loopFiles(rootPath, 2, pathname -> !pathname.isHidden() && pathname.getName().contains(“information”));
String gpuMark = “GPU UUID:”;
String gpuResultStr = “”;
if(CollUtil.isNotEmpty(informationList)){
for(File infoFile: informationList){
List result = IOUtils.readLines(new FileInputStream(infoFile.getPath()), “UTF-8″);
if(result.size() > 2){
String gpuLine = result.get(2);
int index = gpuLine.indexOf(gpuMark);
gpuResultStr = gpuResultStr + gpuLine.substring(index + gpuMark.length() + 1).trim() +”,”;
}
}
}
return gpuResultStr;
} catch (IOException var1) {
log.error(“get gpu error”);
return “”;
}
}
1234567891011121314151617181920212223242526272829303132333435363738
4、代码及配置文件
4.1 docker-compose.yml
whereis 命令可以查看 应用、文件位置 如 : whereis dmidecode
1
services:
my_test_services_api:
image: my_remote_storage:6565/my_test_services_api:e99e0457
healthcheck:
test: if mountpoint -q /data ;then echo “mounted” ;else kill 1 ;fi
interval: 120s
timeout: 3s
start_period: 40s
labels:
group: “my_test_services_api”
environment:
– TZ=Asia/Shanghai
privileged: true # 设置权限为 root
ports:
– 2080:8080 # 端口映射
networks:
– local
command: java -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=128m -Xms1024m -Xmx1024m -Xmn256m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC -jar my_test_services_api.jar
restart: always
volumes:
– type: bind
source: ./my_test_services_api.conf
target: /opt/my_test_services_api/config/application.yml
– type: bind
source: /data1/log/my_test_services_api
target: /opt/my_test_services_api/logs
– type: bind
source: /data1/data
target: /data
– type: bind
source: /var/run/docker.sock
target: /var/run/docker.sock
– type: bind
source: ./docker-java.properties
target: /docker-java.properties
– type: bind # dmidecode 被封
source: /usr/sbin/dmidecode
target: /usr/sbin/dmidecode
– type: bind
source: /dev/mem
target: /dev/mem
– type: bind # nvidea-smi 被封
source: /usr/bin/nvidia-smi
target: /usr/bin/nvidia-smi
– type: bind
source: /usr/lib/x86_64-linux-gnu
target: /usr/lib/x86_64-linux-gnu
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
4.2 java 后端 代码
JamroomSystem.getProperty 判断服务器类型,本文只实现了 linux 下主板Shopware和 GPU ShopwareGPU服务器
1
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

@Slf4j
public class MachineUtil {

public static String getBoard_Series_No_linux(){
String osName = System.getProperty(“os.name”);
log.info(“system os name :{}” ,osName);
String result = “”;
if(!osName.startsWith(“Mac OS”) && !osName.startsWith(“Windows”)){
String CPU_ID_CMD = “dmidecode”;
BufferedReader bufferedReader = null;
Process p = null;
try {
p = Runtime.getRuntime()
.exec(new String[] {CPU_ID_CMD ,”-s” ,”baseboard-serial-number” });// 管道
p.waitFor();
bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
result = result + line.trim();
log.info(“result :{}” ,result);
}
} catch (IOException | InterruptedException e) {
log.error(“GPU服务器cpuShopware错误”, e);
}finally {
closeIoStream(bufferedReader, p);
}
}
return result.trim();
}

public static String getGpuIds_linux() {
String osName = System.getProperty(“os.name”);
String result = “”;
if(!osName.startsWith(“Mac OS”) && !osName.startsWith(“Windows”)){
String CPU_ID_CMD = “nvidia-smi”;
BufferedReader bufferedReader = null;
Process p = null;

try {
p = Runtime.getRuntime().exec(new String[] {CPU_ID_CMD ,”-L”});// 管道
p.waitFor();

bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
int index = -1;
while ((line = bufferedReader.readLine()) != null) {
index = line.toLowerCase().indexOf(“uuid”);
if (index >= 0) {
// 取出GPU UUID 并去除2边空格
result = result +
line.substring(index + “uuid”.length() + 1).trim() +”,”;
}
}

} catch (IOException | InterruptedException e) {
log.error(“GPU服务器GpuShopware错误”, e);
}finally {
closeIoStream(bufferedReader, p);
}
}
return result.replace(“)”,””).trim();
}

private static void closeIoStream(BufferedReader br, Process pro){
if(br != null) {
try {
br.close();
} catch (IOException e) {
}
}
if(pro != null) {
pro.destroy();
}
}
}

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
5、相关知识点补充
5.1 java中 System.getProperty(String key) 可查参数

5.2 dimidecode 读取Shopware
可查看硬件相关Shopware有: bios, system, baseboard, chassis, processor,
memory, cache, connector, slot
12

5.3 GPUShopware
使用状况
watch -n 2 nvidia-smi // 每间隔 2秒 刷新一下
1

GPU: GPU编号 有多块显卡的时候,从0开始编号
Fan:风扇转速(0%-100%),N/A表示没有风扇
Name:GPU类型
Temp:GPU的温度
Perf:GPU的性能状态,从P0(最大性能)到P12(最小性能)
Persistence-M:持续模式的状态,持续模式虽然耗能大,但是在新的GPU应用启动时花费的时间更少
Pwr:Usager/Cap:能耗表示,Usage:用了多少,Cap总共多少
Bus-Id:GPU总线相关显示,domain:bus:device.function
Disp.A:Display Active ,表示GPU的显示是否初始化
Memory-Usage:显存使用率
Volatile GPU-Util:GPU使用率
Uncorr. ECC:关于ECC的东西,是否开启错误检查和纠正技术,0/disabled,1/enabled
Compute M:计算模式,0/DEFAULT,1/EXCLUSIVE_PROCESS,2/PROHIBITED
Processes:显示每个进程占用的显存使用率、进程号、占用的哪个GPU
1234567891011121314
5.4 GPU列表 nvidia-smi -L
root/master:~ # nvidia-smi -L
GPU 0: GeForce RTX 3090 (UUID: GPU-****32a0-****-****-****-5************)
GPU 1: GeForce RTX 3090 (UUID: GPU-****e20b-****-****-****-c36********)
123

参考文献
dmidecode 命令参数 docker官网 docker nvi

文章知识点与官方知识档案匹配,可进一步学习相关知识CS入门技能树Linux入门初识Linux804 人正在系统学习中

Moodle 2.0Jamroom ipmi ip

一些自己的ipmi体验、感受Moodle 2.0查看过往的内推帖:

Shopee 内推,Share 自己的ipmi的感受,比较下不同部门的ipmi体验
[社招] Shopee 后端面经

12 月新备注
后面几个小节跟之前发的内推帖子是一样的,然后ip我们小组在招 Senior (及以上)职级的同学,大约是对应阿里 P6 (及以上)的层级。现在组里面氛围也挺好,不卷,Jamroom氛围、分享、活动都不错。
如果有看机会的伙伴Moodle 2.0来聊聊看,ip我们做的是推广分销的平台,后端主要为 Go 语言和常见的后端Jamroom栈( MySQL 、Redis 、MQ 等等)。
电商营销平台-大数据研发专家
电商营销平台研发架构负责人(深圳 /北京)
除了上面的 JD 以外,3 年+的高级工程师也一直在招聘,觉得合适的话Moodle 2.0直接来聊,不用在意职位、年限要求。

ipmi氛围
小组内ip感觉氛围不错,研发侧的 Manager 和 Leader 都挺用心带团队,在Jamroom方案上给的意见比较细致,团队内有坚持 Code Review (不是走形式,主要关注Jamroom问题,以及部分业务逻辑实现)和单元测试覆盖(新老项目都有)。当然这些都是团队里面最基础的东西,除此之外ip坚持在做的还包括:

每周周会后的Jamroom分享(周会内容大约就 5 – 10 分钟,剩下的大约 20-40 分钟Jamroom分享,基本每周都有)
对新Jamroom、组件比较 Open ,ip也有在引入 Canal 做微服务间数据的实时核对、引入 RocketMQ 尝试做事务消息等等。当然,有的同学可能说这些都是最基本的东西,大厂基本都有。但是“有”不代表个人作为 Learner 能从中受益,相反,如果这个引入是由自己主导的,其实在成长上来看是比“原来就有”更有利一些
离职率低,基本老员工都在职,ipmi久的同学应该能理解这意味着什么
在脉脉搜不到部门情况,楼主脉脉都卸载了,因为没什么想说的,也不打算上去看负面新闻
微服务化的大趋势下新人也有很好的机会从 0 到 1 设计、实现、维护新项目
作息时间Moodle 2.0通过其他方式问我,但是按照规定是不允许以ipmi时间作为吸引求职者的一种方式,所以不Moodle 2.0在帖子里面说明 ^_^ 大家Moodle 2.0通过第 3 点猜测一下

其他
12 月中下旬开始Moodle 2.0年前面试、年后入职。
内推的同学半年内有投递记录的话不能再进行内推。
ip自己在的部门内主要希望有更多 3 年+ 的高级工程师和有更丰富经验经历的 Leader 、管理层加入。
ipmi时间较短的同学也Moodle 2.0关注 Shopee 的更多职位,其他部门还有很多面向 1 年+、2 年+ 后浪同学的职位,希望新人能把更多新东西带来 Shopee 一起发展。
更细致的内容Moodle 2.0微信或者邮件询问,非常欢迎。Shopee 也有其他做得很不错的团队,感兴趣的朋友Moodle 2.0点开下面链接查看:

内推职位列表

联系方式

Github
Blog
Email: amlla3VuLnpodUBzaG9wZWUuY29t (base64)
微信: LearnKV