LINUX.ORG.RU

Сообщения mrs

 

Не получаю ответа на долгий POST-запрос

Есть трабла с ответом сервера на долгий POST-запрос.

Вкратце:

  • Отправляю curl-ом файл на сервер;
  • Сервер файл принимает, проверяет целостность, заливает данные в БД;
  • Также в процессе обработки принятого файла, происходят некие операции с другими файлами - в основном переименования и обработки внешними утилитами;
  • Весь процесс обработки принятого файла занимает чуть больше часа.

На стороне сервера скрипт обработки завершается без ошибок. На стороне клиента, скрипт заливки ожидает ответа сервера, НО не получает его вплоть до таймаута установленного в curl — отваливается через 10 часов.

На сервере используется связка NGINX + PHP-FPM. Настройки NGINX и PHP-FPM вроде в норме, времени выделено достаточно, памяти хватает, воркеров тоже вроде хватает, в логах нет ни единой ошибки.

Версия PHP на сервере - PHP 7.0.12-1~dotdeb+8.1 (cli) ( NTS )

Подобный запрос, но со временем выполнения около 10 минут отрабатывает как и ожидалось, а вот ответы на долгие запросы куда-то теряются.

В чем тут может быть проблема? Может кто подскажет, куда копать дальше?

 ,

mrs
()

Москва, САО. PHP-программист.

Ищем PHP-программиста (контент менеджера)

Задачи - написание различных скриптов-утилит для обработки, контроля целостности и корректности данных, конвертации файлов, импорта/экспорта данных в БД. Написание библиотек взаимодействия с удаленными сервисами.

Требуются хорошие знания:

  • PHP, стандартных библиотек интерпретатора;
  • Протоколов сетевого взаимодействия;
  • Регулярных выражений;
  • Linux-окружения и bash (или аналогов).

Также:

  • Умение быстро разбираться в технической документации;
  • Умение с высокой точностью оценить сроки на поставленную задачу;
  • Желательно хорошее знание Excel или готовность изучить факультативно.

Будет плюсом:

  • Базовые знания MySQL (умение составлять запросы к БД для получения нужных данных);
  • Представление о NoSQL базах данных (используем Redis и ArangoDB);
  • Знание HTML, CSS, Javascript.

Нужен сотрудник в штат, офис располагается недалеко от метро Речной Вокзал. График трудового дня гибкий, неделя 5/2.
Заработная плата от 50 т.р., испытательный период: 1 месяц. Возможности профессионального и карьерного роста.

Объём работы в контексте управления контентом неограничен.

Контакт: +7 (9²9) 5зз 59 ²7, aladin.it@yandex.ru

 ,

mrs
()

Нужно написать PHP-скрипт обхода ссылок

Ссылки могут быть как непосредственно на файлы, так и на файлы/каталоги в облачных хранилищах (YandexDisk, GoogleDrive, MailRuCloud, Dropbox).

На входе имеется ссылка, пароль-логин (если нужна Simple-авторизация), регулярка имени файла (если ссылка ведет на каталог).

Нужно, в общем случае - авторизоваться, найти заданный файл, скачать его на локальный диск, и если файл находится в архиве (могут быть zip,rar,7z,tar.gz,tgz) то распаковать его.

Скрипт нужно написать на PHP7 для Linux-окружения, используя следующий шаблон:

$_CNF = $_CNF ?? (object)array(
  'connection' => (object)array( // if connection to external service lost, then
    'retries' => 5,              // reconnect 5 times
    'sleep' => 20,               // wait 20 seconds for next retry
  ),
);

$_PRO = $_PRO ?? [
// 77 - идентификатор группы ссылок
77 => [
// 3 - прямые ссылки на файлы
  3 => [
// 10 - id файла
    10 => [
// [0] - скрипт получения (если сложная авторизация)
      'auth_script',
// [1] - ссылка на файл
      'http://domine.ru/file.dat',
// [2] - имя файла или регулярка имени файла
      null,
// [3] - логин (если пустой, то нет аутентификации)
      'username',
// [4] - пароль
      'password',
// [5,6] - не используются
      null, 0 ],
    11 => [ /* данные другого файла с id 11 */ ],
  ],
// 4 - ссылки на каталоги / файлы в облачных хранили
  4 => [
    15 => [ 'auth_script',
      'https://yadi.sk/d/2329jdsfjd',
      '/.*filename.*\.dat/ui',
      'username', 'password', null, 0 ],
    18 => [],
  ],
],

// 79 - другая группа с прямыми ссылками и облачными
79 => [], ];

// получение файлов по прямым ссылкам
function fetch_files_2() { global $_CNF, $_PRO;
  foreach( $_PRO as $id => $inf ) if( isset( $inf[3] ) ) foreach( $inf[3] as $fid => $arg ) {
    // получить файл и сохранить его во временный каталог
    // если это архив (определять по расширению), то нужно распаковать
    //
    // if( ERROR ) { log() and continue; }
  } return 0;
}

// получение файлов по ссылкам на облачные хранилища
function fetch_files_3() { global $_CNF, $_PRO;
  foreach( $_PRO as $id => $inf ) if( isset( $inf[4] ) ) foreach( $inf[4] as $fid => $arg ) { }
  return 0;
}

Хотелось бы в итоге видеть готовый к боевому использованию компонент обхода ссылок. Оплата по договоренности. Контакт: aladin.it@yandex.ru или +7-925-3420026

 

mrs
()

Ищу занятие

Ищу достойное и интересное занятие с возможностью повышения квалификации в области системного или прикладного программирования с целью последующего трудоустройства...

Немного о себе: Ранее занимался локализацией игр (выстраивание процесса локализации, написание вспомогательных утилит, тестирование и сборка мастер дисков), потом увлекся веб программированием, а конкретнее портированием/локализацией социалок из фейсбука в другие сети: несколько завершенных и окупившихся проектов с миллионной аудиторией (работал с PHP, ROR, JS/AS, C#, HTML, CSS, MySQL, MSSQL, Redis и др.)

В данный момент интересно программировать на C/ASM, языки и архитектуру x86 процессоров знаю, немного знаком с архитектурой ОС Linux, в чем собственно и хотелось бы повысить свои знания. Готов к участию в любом полезном для пользователя и интересном для меня проекте. Могу уделять 2-3 часа в сутки безвозмездно или больше времени за символическую плату, так сказать “на еду”...

В качестве примера личных разработок могу предоставить исходники многопоточного системного логгера (альтернатива syslog daemon). Эту поделку не выкладывал нигде, так как занимался ей только для самообразования. В общем, вышлю, если будет интересно посмотреть на код.

Мой контакт в профиле.

 , ,

mrs
()

Последствия отключения root'а

Приветствую,

Отключил root правкой /etc/passwd:

root:x:0:0:root:/root:/sbin/nologin

все вроде работает правильно, за исключением bash-скриптов запускаемых по крону от root'a.

дело в том, что крон в системе нестандартный, задания запускаются следующим кодом (исходник на Си):

if ((pid = fork()) == 0) {
	syslog(LOG_DEBUG, "executing %s", job->command);

	dup2(infd, STDIN_FILENO);
	dup2(outfd[1], STDOUT_FILENO);
	dup2(outfd[1], STDERR_FILENO);

	/* close any open files */
	close(infd);
	close(outfd[0]);
	close(outfd[1]);

	closelog();

	setsid();

	execle(shell, shell, "-c", job->command, NULL, env);

	doLogOpen(LOG_CRON, LOG_PID, "%s(child)", progName);
	syslog(LOG_ERR, "Couldn't exec '%s -c %s': %m", shell, job->command);

	_exit(1);
}

если скрипт вызывать из консоли «$ sudo /etc/script», то скрипт выполняется корректно, но если вызвать его из крона, то в ответ получаю сообщение «This account is currently not available.»

Подскажите, как отключить рута, чтобы возможно было выполнять скрипты из крона? Или может быть надо менять код крона, что бы он не пытался логинится для выполнения скриптов?

Операционка CentOS 6.5

mrs
()

[openvz/centos6] Обновление контейнера с помощью yum update...

Подскажите, возможно ли корректно обновить компоненты ОС в OpenVZ контейнере?

Вопрос возник потому как после yum update в CentOS6-контейнере, не могу ничего установить с помощью yum. Вот вывод:

[root@test /]# yum install git
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/metalink                                                                                                                  |  17 kB     00:00
Traceback (most recent call last):
  File "/usr/bin/yum", line 29, in <module>
    yummain.user_main(sys.argv[1:], exit_code=True)
  File "/usr/share/yum-cli/yummain.py", line 276, in user_main
    errcode = main(args)
  File "/usr/share/yum-cli/yummain.py", line 129, in main
    result, resultmsgs = base.doCommands()
  File "/usr/share/yum-cli/cli.py", line 434, in doCommands
    self._getTs(needTsRemove)
  File "/usr/lib/python2.6/site-packages/yum/depsolve.py", line 99, in _getTs
    self._getTsInfo(remove_only)
  File "/usr/lib/python2.6/site-packages/yum/depsolve.py", line 110, in _getTsInfo
    pkgSack = self.pkgSack
  File "/usr/lib/python2.6/site-packages/yum/__init__.py", line 883, in <lambda>
    pkgSack = property(fget=lambda self: self._getSacks(),
  File "/usr/lib/python2.6/site-packages/yum/__init__.py", line 668, in _getSacks
    self.repos.populateSack(which=repos)
  File "/usr/lib/python2.6/site-packages/yum/repos.py", line 265, in populateSack
    self.doSetup()
  File "/usr/lib/python2.6/site-packages/yum/repos.py", line 92, in doSetup
    self.ayum.plugins.run('postreposetup')
  File "/usr/lib/python2.6/site-packages/yum/plugins.py", line 184, in run
    func(conduitcls(self, self.base, conf, **kwargs))
  File "/usr/lib/yum-plugins/fastestmirror.py", line 191, in postreposetup_hook
    all_urls = FastestMirror(all_urls).get_mirrorlist()
  File "/usr/lib/yum-plugins/fastestmirror.py", line 349, in get_mirrorlist
    self._poll_mirrors()
  File "/usr/lib/yum-plugins/fastestmirror.py", line 393, in _poll_mirrors
    pollThread.start()
  File "/usr/lib64/python2.6/threading.py", line 474, in start
    _start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread
[root@test /]#

В остальном операционка вроде осталась работоспособна. Однако, искал решение вопроса восстановления yum, но нашел несколько упоминаний, что после обновления OVZ-контейнеров перестают работать те или иные компоненты ОС. Может существуют какие-либо особенности обновления системы в контейнерах?

mrs
()

[Redmine] таблицы

Кто-нибудь знает, может есть для Redmine плагин, реализующий нормальные таблицы, подобные GoogleSpreadSheet?

 

mrs
()

[RoR/Highload] архитектура продакшн площадки

Есть задача развернуть продакшн площадку для высоконагруженного Ruby on Rails приложения. Площадка будет состоять из программного балансировщика нагрузки + несколько RoR-фронэндов + кеширующие сервера + сервера баз данных. С БД и кешированием все понятно, а вот с двумя первыми компонентами этой архитектуры есть вопросы, которые хотелось бы обсудить. Насколько я понял, для фронтэндов выбор хоть небольшой, но имеется:
-- nginx + thin
-- nginx + unicorn
-- nginx + phusion passenger

Какие особенности есть у каждого из этих сочетаний и что на ваш взгляд будет показывать наилучшие результаты по производительности? Есть ли другие варианты, сравнимые по производительности и использованию ресурсов ОС с вышеперечисленными?

На счет балансировки нагрузки, что бы вы посоветовали использовать на продакшене в данном случае?

mrs
()

[gcc/c] необычные макросы

знаю есть возможность использовать макросы с переменным числом аргументов, типа:

#define msg( format, ... ) printf( format, args )

можно ли во время препроцессинга узнать количество указанных аргументов ?

mrs
()

[gcc + inline asm] привязка к регистрам

пробую использовать inline asm в gcc, например есть такой макрос:

#define __syscall3a( name, a,b,c ) ({\
	unsigned long ret;\
	__asm__ __volatile__(\
		"syscall" : "=a"(ret) :\
		"a"(__NR_##name),"D"(a),"S"(b),"d"(c) :\
		"memory","cc","r11","cx");\
	(long int)ret; })

это системный вызов с тремя параметрами, по идее всё предусмотрено и выполняется корректно, но не всегда. иногда gcc/gas подбирает другие регистры для name,a,b или c, а нужны именно указанные в строке входных регистров... попробовал ещё такой вариант кода:

#define __syscall3b( name, a,b,c ) ({\
	unsigned long ret;\
	register long int _n __asm__("%rax") = (long int)(__NR_##name);\
	register long int _a __asm__("%rdi") = (long int)(a);\
	register long int _b __asm__("%rsi") = (long int)(b);\
	register long int _c __asm__("%rdx") = (long int)(c);\
	__asm__ __volatile__(\
		"syscall" : "=a"(ret) :\
		"r"(_n),"r"(_a),"r"(_b),"r"(_c) :\
		"memory","cc","r11","cx");\
	(long int)ret; })

тоже работает корректно, НО иногда при компиляции получаю ошибку: «error: can't find a register in class ‘AREG’ while reloading ‘asm’»

подскажите, если ли варианты улучшить ситуацию с инлайном в данных случаях, кроме отказа от него? может быть существуют какие-нибудь «хитрые» ключики компиляции?

mrs
()

[x86_64/syscall/libc] переменная errno

В чем суть наличия этой переменной? Насколько я знаю, Linux syscall возвращает в %rax отрицательное значение этой переменной, если ядро обнаружило ошибку во время исполнения вызова. А затем врапер из стандартной библиотеки переносит это значение в потокозависимую переменную errno и возвращает -1.

Почему нельзя возвращать отрицательный номер ошибки, чтобы приложение самостоятельно анализировало возвращаемое значение?

Также, в одной из статей в сети нашел упоминание, что errno - это устаревший метод определения ошибок. У меня пока что опыт в программировании для Linux небольшой, но вроде других методов определения ошибок в C я не встречал, может чего упустил? Существуют ли другие методы, не основанные на этой глобальной переменной errno?

mrs
()

[asm/c] псевдооператоры .weak & .globl

Допустим есть функция на ASM, которая вызывается из модуля на C. В чем отличия в применении этих псевдооператоров при объявлении имени функции?..

В мануале говориться, что .weak указывает на «слабое» связывание, в отличии от .globl. Подскажите, как это понимать в данном контексте?

mrs
()

[x86_64/asm/c] использование параметров в C-функции

Согласно x86_64 ABI (http://www.x86-64.org/documentation/abi.pdf) параметры в C-функцию передаются через регистры... Отлично! Однако, допустим, есть следующий стартап код (test.s):

.text
.globl _start
_start:

xorq %rbp, %rbp		# set frame pointer to zerro, as per abi

popq	%rdi				# %rdi = argc
movq	%rsp, %rsi		# %rsi = argv

movq	%rdi, %rax
incq	%rax
shlq	$3, %rax
movq	%rsp, %rdx
addq	%rax, %rdx		# %rdx = arge

andq	$-16, %rsp		# align stack pointer to 16 bytes
pushq	%rax				# garbage (8 bytes)
pushq	%rsp				# stack pointer (8 bytes)

call main

movq %rax, %rdi		# %rax - retvalue
movq $60, %rax			# 60 - exit syscall number
syscall

Также есть функция main (test.c):

int main( int argc, char** argv, char** arge ) {
	int i;
	for( i=0; arge[i]; ++i );
	return i;
}

Далее компилируем, убираем лишнее и дизассемблируем:

$ gcc -nostdinc -nostdlib -fno-builtin -o test test.s test.c
$ strip ./test
$ objdump -d ./test

Получаем следующий дамп:

./test:     file format elf64-x86-64

Disassembly of section .text:

00000000004000b0 <.text>:

# _start:
  4000b0:       48 31 ed                xor    %rbp,%rbp
  4000b3:       5f                      pop    %rdi
  4000b4:       48 89 e6                mov    %rsp,%rsi
  4000b7:       48 89 f8                mov    %rdi,%rax
  4000ba:       48 ff c0                inc    %rax
  4000bd:       48 c1 e0 03             shl    $0x3,%rax
  4000c1:       48 89 e2                mov    %rsp,%rdx
  4000c4:       48 01 c2                add    %rax,%rdx
  4000c7:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
  4000cb:       50                      push   %rax
  4000cc:       54                      push   %rsp

# call main
  4000cd:       e8 0e 00 00 00          callq  0x4000e0
  4000d2:       48 89 c7                mov    %rax,%rdi
  4000d5:       48 c7 c0 3c 00 00 00    mov    $0x3c,%rax
  4000dc:       0f 05                   syscall
  4000de:       90                      nop
  4000df:       90                      nop

# main
  4000e0:       55                      push   %rbp
  4000e1:       48 89 e5                mov    %rsp,%rbp

# !!! move parameters back to memory
  4000e4:       89 7d ec                mov    %edi,0xffffffffffffffec(%rbp)
  4000e7:       48 89 75 e0             mov    %rsi,0xffffffffffffffe0(%rbp)
  4000eb:       48 89 55 d8             mov    %rdx,0xffffffffffffffd8(%rbp)
  4000ef:       c7 45 fc 00 00 00 00    movl   $0x0,0xfffffffffffffffc(%rbp)
  4000f6:       eb 04                   jmp    0x4000fc
  4000f8:       83 45 fc 01             addl   $0x1,0xfffffffffffffffc(%rbp)
  4000fc:       8b 45 fc                mov    0xfffffffffffffffc(%rbp),%eax
  4000ff:       48 98                   cltq
  400101:       48 c1 e0 03             shl    $0x3,%rax
  400105:       48 03 45 d8             add    0xffffffffffffffd8(%rbp),%rax
  400109:       48 8b 00                mov    (%rax),%rax
  40010c:       48 85 c0                test   %rax,%rax
  40010f:       75 e7                   jne    0x4000f8
  400111:       8b 45 fc                mov    0xfffffffffffffffc(%rbp),%eax
  400114:       c9                      leaveq
  400115:       c3                      retq

Из которого видно, что параметры, переданные в функцию main, перекладываются из регистров в память, и потом уже используются...

Это - что, шутка такая? (:

Почему не юзаются непосредственно регистры?

mrs
()

Сервисы, совместимость с chkconfig

Подскажите, где можно почитать о синтаксисе скрипта запуска сервисов в линуксе? Если точнее, то интересует что именно означают числа после «chkconfig:» в скрипте запуска, вот например здесь:

# Startup script for anacron
#
# chkconfig: 2345 95 05
# description: Run cron jobs that were left out due to downtime
# pidfile: /var/run/anacron.pid

числа «2345 95 05», что это такое?

mrs
()

SIGKILL и «легковесные» дочки

Подскажите, как правильно удалять дочерние потоки из памяти после завершения родительского процесса с помощью сигнала SIGKILL?

Думал сделать примерно так:

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <sched.h>
#include <sys/wait.h>

static time_t current_sec = 0;
static volatile long int counter = 0;

int thread_f( void *a ) {

	while( ++counter < 300 ) {

		if( (current_sec + 3) < time(0) ) break;
		sleep( 1 );

	}

	printf( "(i) closing thread %d, %s\n", getpid(),
		counter < 300 ? "parent died... :(" : "everything is OK!" );

	return 0;
}

#define N_THREADS 10

int main( int n, char** a ) {

	int i;
	pid_t tid[ N_THREADS ];
	char tstack[ N_THREADS<<12 ];

	current_sec = time(0);

	for( i=0; i<N_THREADS; ++i ) {
		tid[ i ] = clone( thread_f, tstack + ((i+1)<<12),
			CLONE_FILES|CLONE_FS|CLONE_SIGHAND|CLONE_SYSVSEM|CLONE_VM, 0 );
	}

	while( counter < 300 ) {
		current_sec = time(0);
		usleep( 500000 );
	}

	for( i=0; i<N_THREADS; ++i ) waitpid( tid[ i ], 0, 0 );

	printf( "(i) closing parent\n" );

	return 0;
}

Но есть нюансы. Например малая точность определения отсутствия предка, а также возможен случай когда предка просто усыпили с помощью SIGSTOP.

mrs
()

особенности ftok

ftok возвращает разные ключи при одинаковых входных параметрах... почему?

код следующий:

#include <...>

static bool work = false;

void sig_handler( int sn ) {
  if( sn == SIGTERM ) {
    work = false;
  }
}

int main() {

  /* daemonize */

  key_t shm_key = ftok( "/var/run/mydaemon.pid", 1 );
  printf( "(i) key = %d\n", shm_key );

  int shm_id = shmget( shm_key, 0x10000, 0666 );
  if( shm_id == -1 ) shm_id = shmget( shm_key, 0x10000, IPC_CREAT|0666 );
  void *ptr = shmat( shm_id, 0, 0 );
  signal( SIGTERM, sig_handler );

  work = true;
  while( work ) pause();

  /* shmctl( shm_id, IPC_RMID, 0 ); */
  shmdt( ptr );
  return 1;

}

вот лог из консоли:

$ g++ -static -o mydaemon mydaemon.cpp
$ ./mydaemon
(i) key = 33587520
$ pkill -SIGKILL mydaemon
$ ./mydaemon
(i) key = 33587520
$ pkill -SIGTERM mydaemon
$ ./mydaemon
(i) key = 33587510

первый раз закрываю именно с помощью SIGKILL, т.е. по идее разделяемый сегмент остается в памяти, второй раз SIGTERM, и только после второго закрытия, ключ меняется на другой... почему? по идее ведь должен генерироваться тот же...

mrs
()

RSS подписка на новые темы