分类目录归档:技术

docker下ElasticSearch的坑之重启物理机

重启物理机后,容器无法正常启动,提示:

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

官方文档只有设置sysctl -w vm.max_map_count=262144,然而该设置在重启后会被重置,于是我们要将该设置固化:

echo "vm.max_map_count=262144" > /etc/sysctl.conf
sysctl -p

WordPress迁移中产生的一些问题

前几天,我更改了wordpress的ssl证书生成方式,于是噩梦开始了。
由于我的wordpress是用docker容器搭建的,结果重建容器后,wp-config.php文件也被重置了。看来挂载/var/www/html文件夹是非常必要的。

无限重定向

不知道为什么wordpress为什么不默认支持https,需要在wp-config.php头部添加:

$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_LOGIN', true);
define('FORCE_SSL_ADMIN', true);

这样就能正常进入网站了。

WP Statistics(统计)插件和评论显示IP错误

一般使用反向代理或CDN后,显示正确的评论IP只需要在wp-config.php头部添加:

if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $list = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
  $_SERVER['REMOTE_ADDR'] = $list[0];
}

然而WP Statistics 12.6.3 中,这个设置并不奏效。我调试了一番后,发现插件获取IP用的既不是REMOTE_ADDR,也不是HTTP_X_REAL_IP,而是HTTP_X_FORWARDED_FOR的最后一个IP。真不知道作者是什么思路写下这种bug。
为了防止作者再写出别的bug,我直接伪造所有IP信息,把上面的代码修改为:

if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
  $list = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
  $_SERVER['REMOTE_ADDR'] = $list[0];
  $_SERVER['HTTP_X_REAL_IP'] = $list[0];
  $_SERVER['HTTP_X_FORWARDED_FOR'] = $list[0];
}

丢失操作前的文章

谁叫你不勤备份啊!修改服务器前一定要备份。

写了一个1fichier的.net SDK

最近想用1fichier的网盘,顺手搞了一个.net SDK,项目地址 点我

1fichier优点如下:

  • 价格便宜
  • 可以使用FTP上传(不能用FTP下载)
  • 下载速度稳定,国内1~2MB/S
  • 可以同时上传100个文件
  • 没有容量限制
  • 可以上传单个最大100GB文件

1fichier限制如下:

  • 每秒最多只能发出3个API请求
  • 下载文件需要调用API获取临时下载地址(5分钟有效),每有一个文件就要调用一次
  • 只有付费用户才能调用除上传外的API
  • 普通用户下载要排队,一般要等几十分钟
  • 如果分享给其他用户直链(即hot link或CDN),需要消耗CDN流量点数,未付费用户和Access用户没有CDN流量,Premium用户每月有100GB的CDN流量。

总的来说,1fichier上传容易、下载麻烦,不适合备份照片、分享文件,只适合备份不需要经常下载的大文件。

C#全排列的泛型函数实现

C++、Python都有自带的库函数可以实现全排列的遍历,然而C#却没有。
我这里简单实现了一个泛型函数:

public static class Permutation
{
    /// <summary>
    /// 获取全排列,第一次调用前必须从小到大排序。
    /// </summary>
    /// <typeparam name="T">参数类型</typeparam>
    /// <param name="list">全排列数组</param>
    /// <returns>是否生成成功。</returns>
    public static bool NextPermutation<T>(IList<T> list)
        where T : IComparable<T>
        {
            int topIndex = -1;
            int length = list.Count;
            for (int i = length - 1; i > 0; --i)
            {
                if (list[i].CompareTo(list[i - 1]) > 0)
                {
                    topIndex = i;
                    break;
                }
            }

            if (topIndex < 0)
            {
                list.Reverse(0);
                return false;
            }

            int swapIndex = topIndex;
            for (int i = topIndex + 1; i < length; ++i)
            {
                if (list[topIndex - 1].CompareTo(list[i]) >= 0)
                {
                    break;
                }
                else
                {
                    swapIndex = i;
                }
            }

            list.Swap(swapIndex, topIndex - 1);
            list.Reverse(topIndex);
            return true;
        }

    public static void Swap<T>(this IList<T> list, int a, int b)
    {
        T temp = list[a];
        list[a] = list[b];
        list[b] = temp;
    }

    public static void Reverse<T>(this IList<T> list, int index)
    {
        int max = list.Count - 1;
        int length = (max - index) / 2;
        for (int i = 0; i <= length; ++i)
        {
            list.Swap(index + i, max - i);
        }
    }
}

使用时只需要排序后循环调用Permutation.NextPermutation即可。
此处使用的方法来自于Keosu全排列各种实现(非递归、递归),修复原文方法1的一个小bug后,用C#封装而成。