软路由系列–Others

Others

还有一些其他的点,顺带记录下

Samba

安装软件后,配置目录,添加smb用户和密码

apt install samba
vim /etc/samba/smb.conf

[global]
  workgroup = SAMBA
  security = user
  passdb backend = tdbsam
  printing = cups 
  printcap name = cups
  load printers = yes
  cups options = raw

[other]
  comment = other
  path = /data/other
  browseable = yes
  writable = yes
  public = yes
  write list = +smbuser1  
smbpasswd -a smbuser1  # 添加用户,设置密码,这个密码是samba的密码

把Sonarr的docker IP添加到Transmission 访问白名单

Transmission我们是docker安装的,所以白名单的IP是docker的IP,我们使用以下命令获取到sonarr的IP

docker network inspect sonarr_default

假设得到的是172.18.0.1,那么我们在transmission的配置文件中添加以下内容即可,这样的话,sonarr就可以访问transmission了

Read more →

软路由系列–Docker

Read more →

软路由系列–续篇–代理和DNS设置

Read more →

软路由系列–路由器系统-Ubuntu

软路由的系统

软路由系统安装 篇1也是写于三年前左右了

自己的软路由系统一直在用linux发行版,第一次使用软路由是2018年了,当时使用的是centos7,还是小马的软路由n3700,当时自己加配了8G内存,也就是4C8G,固态硬盘120,而后这个固态也在今年挂掉了,4月份还重装了下系统,由于配置还在,所以当时继续沿用了centos7

不过呢,最近刚好入手了一个零刻的小主机,i3-N305, 8核8线程,1.8GHz->3.8GHz, 16G,512G。最近也是想换个系统了,因为centos7的软件源太老了,带的内核还是3.10的,官方也没人维护了,索性切换到Ubuntu 22.04.02了,内核5.15(晚些换成6)

Ubuntu 22.04.02

我选择的是server版本,安装的时候,根本不会跳出来GUI,全部命令行,超级nice,而且很贴心的自动把SSH远程访问勾选了,只要安装好,就可以使用远程登陆了,也不需要自己开启了。

开启软路由功能

apt install bridge-utils

编辑 netplan yaml文件,这台主机只有两个网口,所以搞个bridge,而后一个网口当做wan口,一个网口当做lan口,把lan口加入到bridge中即可

vim /etc/netplan/00-installer-config.yaml
network:
  ethernets:
    enp1s0:
      dhcp4: true
    enp2s0:
      dhcp4: no
  bridges:
    br0:
      dhcp4: no
      addresses: [10.0.1.1/24]
      nameservers:
        addresses: [8.8.8.8]
      interfaces: [enp2s0]
  version: 2

应用配置,并且查看信息

netplan apply

brctl show

类似以下就成功了,其中enp2s0 就是lan口,你下面挂其他wifi放大器,或者交换机等等

bridge name	bridge id		STP enabled	interfaces
br0		8000.6aa01d4c1f71	no		enp2s0

开启dhcp服务,给其他设备分配ip或者提供dns服务

 apt install dnsmasq

编辑配置文件, 设置dhcp的网段,dns,dns解析文件,端口

vim /etc/dnsmasq.conf

interface=br0
dhcp-range=10.0.1.2,10.0.1.254,72h
dhcp-option=6,10.0.1.1
resolv-file=/etc/resolv.dnsmasq.conf
port=1053 # 这里我改成了1053,我其他地方有个dns服务,端口是53,所以这里改成了1053

如果有自己的dns proxy,这里要注意,ubuntu有个默认的resolv.service,可以把他禁用掉,不然会冲突

Read more →

go解决c10k problem(二)–db版下单场景

TL;DR

前言

这是一篇去年8月写的文章,本来是希望达到10k, 不过实际测试并没有成功,最终达到了1000+的事务,完成C10K的一个K,还有9个 :(

DB选择

DB 类型 业务 io
Mysql sql,支持事务,有缓存 强sql,强类型,类似java B & B+
Postgres sql,支持事务
Mongo nosql,key-value DB,读很快 弱sql,非强制,类似js B+
Redis nosql just kv,代码复杂
sqlite3 sql 强sql,支持事务 Btree

初步结论,理论上是随便用,先用sqlite3把,如果性能达不到,再来排查原因和更改DB

业务场景

我们设计一个sticker网站,可以售卖sticker,用户可以购买sticker,sticker是有库存的,如果用户的余额足够,则可以售卖,另外售卖的过程中,如果库存没了的话,需要回滚订单。

主要对象

  • 用户
  • 商品,库存字段也在商品身上
  • 订单

主要流程

  • 商品的详情页面,get v1/api/sticker/:id
  • 商品的点赞+1接口,post v1/api/sticker/likes
  • 下单接口,post v1/api/order
  • 订单查看接口,get v1/api/order/:id

表现

get 接口 读

load

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 
10154 ubuntu 20 0 1757000 36888 10020 R 362.7 0.1 2:48.41 main 
9046 ubuntu 20 0 2125668 31976 9876 S 346.3 0.1 2:51.78 server

QPS表现

Read more →

go解决c10k problem(一)

零:缘起

最近两个事情

一个是easeprobe,haocl 对其http probe 做了一个10k的benchmark easeprobe benchmark

一个是读到go memory这篇文章 go-memory-ballast

谈到技术,并发是一个绕不过的话题,从第一家公司单机2万qps,到一个50w+ tps的超大型分布式交易系统。

那么自己能否来简单来测试一下呢? 跑一个web server,来个10k 并发,再来个可观测,看下瓶颈到底在哪里? 如何提升? 说干就干。

一:go http server

goroutine的存在,让go在网络编程这块很高效,也有很多优秀的http 框架,比如 gin echo fasthttp

fasthttp 比较快,我们先不读取db和其他,仅让cpu是一个瓶颈,仅写个hello world,收到请求后,返回一行文本。

示例代码

package main

import (
	"fmt"
	"github.com/valyala/fasthttp"
)

// request handler in fasthttp style, i.e. just plain function.
func fastHTTPHandler(ctx *fasthttp.RequestCtx) {
	fmt.Fprintf(ctx, "Hi there! RequestURI is %q", ctx.RequestURI())
}

func main() {
	fasthttp.ListenAndServe(":8087", fastHTTPHandler)
}

二:go http client 压测的client

2.1 压测client选择

  • 简单实现版本,使用time.Sleep 函数,来均匀分布所有的请求到一个server。
  • 复杂实现版本,来一个goroutine的pool,一个http connect的pool,分别控制最大连接数和最大goroutine数目,并且根据请求耗时,动态调整两个pool的大小,然后到一个稳定的状态。
  • 别人现有的,找到一个 go-strees-testing 的项目,可以先用起来

2.2 先选择现有的试试效果

https://github.com/link1st/go-stress-testing

Read more →

typeScript的一个坑

缘起

最近找了个兼职,写了一段node的typescript代码,虽然上次写node还是5年前,但因为使用的框架是midway,写的过程中,几乎没有碰到bug,很自然的感觉,就是spring的那一套,面向对象,依赖注入等,写web还是很方便的。

不过也由于这几年天天看和写java代码,写的时候,很容易就按照面向对象写起来,一切都是class,class的方法等,所以这也是bug的由来。

问题来龙去脉

业务bug简单描述

一个学校有n个老师,每个老师一门课程,期末的时候,老师会给学生打分,学生同时也是一个用户。

问题:在打分的过程中,为了方便,对学生对象list转换成了map,然后每个老师都会对学生的分数进行统计,然后再把统计结果返回给学生,这样就会导致学生的分数被覆盖。发现学生的成绩到最后都是一个老师打的。

复现代码

class User {
    Name: string;
    Age: number;
}

class Student extends User {
    Grade: number;
}

class Teacher {
    Name: string;
    Class: string;
    Students: Student[];
}

const user1 = new User();
user1.Name = 'John';
user1.Age = 30;


const user2 = new User();
user2.Name = 'Jane';
user2.Age = 25;



const users = [user1, user2];

const teacher = new Teacher();
teacher.Name = 'Bob';
teacher.Class = '1A';

const teacher2 = new Teacher();
teacher2.Name = 'Alice';
teacher2.Class = '1B';

const teachers = [teacher, teacher2];

const userMap = users.reduce((acc, cur) => {
    acc[cur.Name] = cur;
    return acc;
  }, {});

const gradeTeacher = new Array<Teacher>();

teachers.forEach(teacher => {
    const students = new Array<Student>();
    const teacherName = teacher.Name;

    Object.entries(userMap).forEach(([key, value]) => {

        let student = new Student();
        student = userMap[key];
        if (teacherName === 'Bob') {
          student.Grade = 100;
        } else {
            student.Grade = 50;
        }
        students.push(student);

    });
    teacher.Students = students;
    gradeTeacher.push(teacher);
});


for (const teacher of gradeTeacher) {
    console.log(teacher); 
}

理论期望的结果

Teacher {
  Name: 'Bob',
  Class: '1A',
  Students: [
    User { Name: 'John', Age: 30, Grade: 100 },
    User { Name: 'Jane', Age: 25, Grade: 100 }
  ]
}
Teacher {
  Name: 'Alice',
  Class: '1B',
  Students: [
    User { Name: 'John', Age: 30, Grade: 50 },
    User { Name: 'Jane', Age: 25, Grade: 50 }
  ]
}

实际结果

Teacher {
  Name: 'Bob',
  Class: '1A',
  Students: [
    User { Name: 'John', Age: 30, Grade: 50 },
    User { Name: 'Jane', Age: 25, Grade: 50 }
  ]
}
Teacher {
  Name: 'Alice',
  Class: '1B',
  Students: [
    User { Name: 'John', Age: 30, Grade: 50 },
    User { Name: 'Jane', Age: 25, Grade: 50 }
  ]
}

why?

可以看到,user 被循环了两次,而且每次都是user1,user2,这样就导致了学生的分数被覆盖。

Read more →

go面试算法系列记录

面试

最近从阿里离职,开始准备面试,刷了一个月左右的leetcode,然后实践出真知,去面试了几家公司。

shopee 算法一面 螺旋矩阵,反向螺旋矩阵

描述要求

给定一个n x n的,打印出一个螺旋矩阵,比如:

输入n= 3,

输出,则打印

9 8 7 2 1 6 3 4 5

思路和解决

其实考察的是对数组的理解,还有矩阵的理解,就是找到矩阵的上下左右边界,遍历即可。反向的话,无非是从高到低遍历,正向的话,是从低到高遍历。

代码

func main() {
    matrix := generateMatrix(3)
    printMatrix(matrix)
}

func printMatrix(matrix [][]int) {
    if matrix == nil || len(matrix) == 0 {
        return
    }
    n := len(matrix)
    for i := 0; i < n; i++ {
        for j := 0; j < n; j++ {
            fmt.Printf("%d ", matrix[i][j])
        }
        fmt.Println()
    }
}

func generateMatrix(n int) [][]int {
	upper_bound, left_bound := 0, 0
	lower_bound, right_bound := n-1, n-1
    // 反向的话,number是最大值
	number := n*n
	var matrix = make([][]int, n)
	for k := range matrix {
		matrix[k] = make([]int, n)
	}
	for number > 0 {
		if upper_bound <= lower_bound {
			for j := left_bound; j <= right_bound; j++ {
				number--
				matrix[upper_bound][j] = number
			}
			upper_bound++
		}
		if left_bound <= right_bound {
			for j := upper_bound; j <= lower_bound; j++ {
				number00
				matrix[j][right_bound] = number
			}
			right_bound--
		}
		if upper_bound <= lower_bound {
			for j := right_bound; j >= left_bound; j-- {
				number--
				matrix[lower_bound][j] = number
			}
			lower_bound--
		}
		if left_bound <= right_bound {
			for j := lower_bound; j >= upper_bound; j-- {
				number--
				matrix[j][left_bound] = number
			}
			left_bound++
		}

	}
	return matrix

}

shopee 算法二面 手写LRU

描述

LRU,即Least Recently Used,最近最少使用,是一种缓存算法,它的主要目的是为了防止缓存中的数据过期,过期后就不能再使用。

Read more →

How to install archlinux on a m1 mac

Reason

I just have installed archlinux on a m1 mac. The reason is that I have a m1 mac.

How to install

Like this:

  1. Download the archlinux iso
  2. Mount the iso
  3. Copy the archlinux folder to the root of the iso
  4. Unmount the iso
  5. Boot the iso
  6. Install the archlinux
  7. Reboot the mac
  8. Enjoy your new linux

wait wait ??? right now is 2022, why the steps are so complicated?

Read more →

华为社招机考-字符串解压缩

Read more →

Go slice的一个坑

问题

最近在刷leedcode,求二叉树的路径和,给定一个二叉树,求所有符合条件的路径。原题见 113. Path Sum II

这道题需要遍历所有的节点,并且记录遍历路径上的节点,可以使用回溯法,深度优先的方法。

不过最近用习惯了广度优先的方法,把二叉树变成一个有序的队列,这种思想很好玩,把多个选择的,需要遍历的变成一个有序的来进行遍历即可,就是一个万能模板。

下面贴下代码

var result [][]int

var ch = make(chan *TreeNode, 100)
var sumChan = make(chan int, 100)
var nodes = make(chan []int, 100)

for len(ch) > 0 {
    for i := 0; i < len(ch); i++ {
        //获取当前节点
        cur := <-ch
        //获取父节点的总和
        parentSum := <-sumChan
        //获取父节点的所有路径节点序列
        parents := <-nodes
        //当前节点的总和
        curSum := parentSum + cur.Val
        //当前节点的序列
        curNodes := append(parents, cur.Val)

        if cur.Left == nil && cur.Right == nil {
            if curSum == targetSum {
                // 添加当前节点序列到结果集
                result = append(result, curNodes)
            }
        } else {
            if cur.Left != nil {
                ch <- cur.Left
                sumChan <- cur.Val + parentSum
                nodes <-  curNodes
            }
            if cur.Right != nil {
                ch <- cur.Right
                sumChan <- cur.Val + parentSum
                nodes <- curNodes
            }
        }

    }
}

大家细读一下,不知道有没有看出来哪里不对,我先贴一下结果 test case

Read more →

软路由系列–你的家庭linux服务器

Read more →

软路由系列–路由器系统&软件篇

软路由的系统

软路由,软字排在了路由器前面,说明软件是软路由的头等大事。

软件分为操作系统和应用程序两类,选择了操作系统,也就选了对应的软件生态。那我们先来看操作系统。

由于我们的路由是一个网络硬件,那么哪个操作系统软件的网络软件最丰富呢?毋庸置疑,就是linux了。windows和macos也是可用的,但没有linux的网络库全和大。

适用路由器的linux操作系统,分为两种,路由器专用系统,和常见的linux发行版。下面分别讲下他们的优缺点。

路由器专用系统

如LEDE/openwrt,爱快,koolshare,是专门为路由器开发的嵌入式系统

优点 自带套件,安装方便,为了软路由而生,有web管理页面,配置管理方便

缺点 软件源没有常见linux发行版多,很多软件需要适配

常见linux发行版

如centos、ubuntu、debian、archlinux等

优点 软件丰富,可以装几乎所有的软件

缺点 配置复杂,安装麻烦,需要一定的shell、系统管理的知识

结论 如果你有一定的动手能力,我推荐你使用linux发行版做你的路由器系统(有一定的硬件配置要求,比如我的是4核赛扬的cpu、2G内存,128G的ssd硬盘+1T的hdd硬盘),如果你路由器配置比较低,那么推荐使用路由器专用系统,占用资源较少。

软路由的软件

假设跟我一样,你选择了安装常见linux发行版,并且为了稳定选择了centos当作操作系统(当然你也可以选择自己的发行版),那么需要安装什么软件才能让他变成一个路由器呢?

软路由拓扑

操作系统安装 centos安装指南官方版

软件列表

  • dnsmasq (必选)提供dns、dhcp等功能
  • iptables (可选)网络利器
  • shadowsocks(可选)网络软件
  • samba(可选) 本地共享
  • adbyby(可选)广告过滤透明代理
  • transmission(可选) bt下载

软件配置指南

1 dnsmasq

由于我家里是光纤,网络运营商自带了一个modem兼路由器。从网上翻了下,找到一个超密,并且超密到路由器,可以设置这个路由器为桥接或者路由功能,如果选择桥接,相当于他什么作用也没有,仅仅是一个光纤信号转换器了,这里我选择的是路由,所以也不需要安装拨号软件了。

首先:设置dhcp server,dns转发,编辑 /etc/dnsmasq.conf

interface=br0 ## 设置你的网络接口,可能与我的不同 dhcp-range=10.0.1.2,10.0.1.254,72h ## 设置你要分配的内网地址段,租约时间,dhcp server resolv-file=/etc/resolv.dnsmasq.conf ## 设置你要使用的默认dns

其次:配置系统转发封包,开启linux路由功能,这样你的linux服务器就是一个路由器了

echo 1 > /proc/sys/net/ipv4/ip_forward sysctl -p net.ipv4.ip_forward = 1

2 shadowsocks 你既然配置了dnsmasq,我推荐你设置全局透明翻墙,使用gfwlist 方案

优点:只要你局域网内的设备连上了你的路由器,所有自动翻墙,无需设置,可以让特定域名根据dnsmasq解析出来的ip强制走ss。 缺点:域名列表需要维护,你可以自己设置,也可以直接使用gfwlist

首先:配置dns解析,配合使用dnsmasq进行dns转发,让你获取正确的ip。 这里如果你安装的dnsmaq已经包含了ipset,则直接使用即可。 把dns请求根据域名路由到特定的服务器,可以把他添加到你的配置文件即可,如下(具体示例配置如下)。

配置说明:对于google.com 的域名dns解析请求转发到本地的5353端口, 并且把解析出来的ip地址放入gfwlist这个ipset集合里面。

Read more →

软路由系列–强大的软路由

Read more →

google pixelbook install ubuntu archlinux

Happy Chinese Luner New Year

So I bought a pixelbook(2017 i5 256G) from Taobao for 450$.Then I began to tweak my pixelbook. First I switch my pixelbook to develop mode.

Install Arch Linux

First I follow a article install archlinux with legacy boot,I spent half my day troubleshooting. install-archlinux-on-pixelbook

Archlinux Problems

I install a console environment, I can’t connect to wifi,but my archlinux usb stick work well,then I found I forget install dialog and wpa_supplicant library,I install those,then I only got a ipv6 address,I know that I did not got a address, Then I go back to my chroot environment install dhclient, I manuly run dhclient got a ipv4 address,then I got connected to internet, then I install a gnome desktop environtment ,but the trackpad is lagged and I can’t stand it. So I switch back to google official linux on chromeos.

Read more →

golang爬虫之无名小说网站

Read more →

使用letsencrypt 来加密自己的个人网站

Read more →

一句话理解反射

Read more →

openwrt 更改登录用户名

Read more →

Inbox Gmail 邮件通知推送收不到

Read more →

typecho 搬家出现500数据库错误

Read more →

openvpn 折腾记

Read more →

欺骗你的进度条

Read more →

利用hosts走向世界

Read more →