Rails, Redis and Sentinel - ruby-on-rails

I have a Redis cluster of 4 nodes, 1 master and 3 slaves, monitored by Sentinel.
Now in rails I need to connect to this cluster, reading from the nearest replica, and writing to the master, the same as I do with MongoDB.
Using the redis-rails gem, how is it possible to configure the cache_store to specify the Sentinels instead of a single node?

I may have missed it, but I wasn't aware that you could configure it to read from the slaves? However, this is my master + 2 slave configuration:
config.cache_store = :redis_store, {
url: 'redis://prestwick/1',
sentinels: [{host: 'prestwick.i', port: 26379}, {host: 'carnoustie.i', port: 26379}, {host: 'birkdale.i', port: 26379}],
role: 'master',
expires_in: 1.hour
}
And in case it's useful, my configuration for a generic REDIS object and Sidekiq (this is in config/initializers/001_redis.rb):
redis_options = {
url: 'redis://prestwick/0',
sentinels: [{host: 'prestwick.i', port: 26379}, {host: 'carnoustie.i', port: 26379}, {host: 'birkdale.i', port: 26379}],
role: 'master'
}
redis_sidekiq_options = {
url: 'redis://prestwick/2',
sentinels: [{host: 'prestwick.i', port: 26379}, {host: 'carnoustie.i', port: 26379}, {host: 'birkdale.i', port: 26379}],
role: 'master'
}
REDIS = Redis.new(redis_options)
Sidekiq.configure_server do |config|
config.redis = redis_sidekiq_options
end
Sidekiq.configure_client do |config|
config.redis = redis_sidekiq_options
end

Related

Rails 5.2 and Sidekiq 5: Errno::EADDRNOTAVAIL: Cannot assign requested address - connect(2) for "localhost" port 25

I'm trying to deliver e-mails with Sidekiq and deliver_later.
In my config/sidekiq.yml I have:
:verbose: true
:concurrency: 25
:queues:
- [mailers, 7]
- [critical, 6]
- [default, 5]
- [low, 4]
In my worker I try do do it with:
Buyer::OffersMailer.instant_for_published_offer(info_to_deliver).deliver_later
I see in Sidekiq admin panel my mailer job is stuck in "Retries" with this error:
Errno::EADDRNOTAVAIL: Cannot assign requested address - connect(2) for "localhost" port 25
My app can send deliver_now e-mails, which I believe rejects assumption that something could be wrong with SMPTP Any ideas, what could be wrong?
Update
In addition emails are not delivered in Production, where my config looks like this:
config.action_mailer.raise_delivery_errors = false
config.action_mailer.default_url_options = { host: "https://myapp.com" }
config.action_mailer.asset_host = "https://myapp.com"
config.action_mailer.perform_deliveries = true
config.action_mailer.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
:address => 'myval',
:port => '587',
:authentication => :plain,
:user_name => 'myval',
:password => Rails.application.credentials.mailgun_smtp_pass,
:enable_starttls_auto => true
}
Since your emails are sent correctly using #deliver_now method, this means that your Mailer config is just fine. Now that aside you should have this in your application.rb config file:
config.active_job.queue_adapter = :sidekiq
and in config\initializers\sidekiq.rb you need to have Redis URL to be configured:
Sidekiq.configure_server do |config|
config.redis = { url: (ENV["REDIS_URL"] || 'redis://localhost:6379/0') }
end
Sidekiq.configure_client do |config|
config.redis = { url: (ENV["REDIS_URL"] || 'redis://localhost:6379/0') }
end
Error in production was due to environment settings in Procfile. As of Sidekiq docs in my case worked RAILS_ENV=production
So my working procfile looks like this:
main_worker: bundle exec sidekiq RAILS_ENV=production
Don't forget to scale your worker if you're using Heroku or Dokku.

Why is Sidekiq running in development environment on server?

in my nginx website config file (/etc/nginx/sites-available/my_website I have set:
passenger_env_var RAILS_ENV staging;
I'm using Sidekiq for sending emails, starting it like this:
bundle exec sidekiq -q mailers -d -L log/sidekiq.log
but my Sidekiq is having environment set to development. Why?
Do I have to set the environment explicitly when starting sidekiq? I thought it is set by the nginx config.
Thanks
Sidekiq's default environment is development. One way to set it is to run sidekiq like this
bundle exec sidekiq --environment production
It could be configured by creating a file under initializers/sidekiq.rb
If Rails.env.development?
Sidekiq.configure_server do |config|
config.redis = { url: 'redis://localhost:6379/0', namespace: "name_{Rails.env}" }
end
Sidekiq.configure_client do |config|
config.redis = { url: 'redis://localhost:6379/0', namespace: "name_{Rails.env}" }
end
elsif Rails.env.staging?
Sidekiq.configure_server do |config|
config.redis = { url: 'redis://redis-xx.xxxx.xxxx.xx.xxx.amazonaws.com:6379/12', namespace: "name_#{Rails.env}" }
end
Sidekiq.configure_client do |config|
config.redis = { url: 'redis://redis-xx.xxxx.xxxx.xx.xxx.amazonaws.com:6379/12', namespace: "name_#{Rails.env}" }
end
end

New Relic Insights is logging pageviews and User Agent info from local machine in dev environment

My New Relic Insights is logging pageviews and User Agent info from local machine in dev environment. I have another dev in another city who is also having the development enviroment pageviews and other info being logged.
When I pull up samples, I see localhost:3000, which is my port.
However, the production info is also being logged.
I have New Relic running using Heroku's default set up. It automatically sets the license key as an environment variable. I do not have the license key anywhere in the app, it only set through an environment variable.
If I pull up my local development environment, navigate to port 3000, and refresh, then query New Relic Insights for events in the last minute, I see my city, my user agent info, my visited url and pageview. Our product is in beta, there is really no chance that an actual user in my location is hitting the same random page.
I have tried turning development mode off, monitor off. I cannot understand how this can be happening.
I do have some files hosted on AWS (images and some js), if that matters
Gemfile
group :production do
gem 'rails_12factor'
gem 'newrelic_rpm'
end
config/newrelic.yml
common: &default_settings
license_key: <%= ENV["NEW_RELIC_LICENSE_KEY"] %>
log_level: info
development:
<<: *default_settings
app_name: app-dev
developer_mode: false
monitor_mode: false
agent_enabled: false
test:
<<: *default_settings
monitor_mode: false
developer_mode: false
agent_enabled: false
production:
app_name: app-prod
monitor_mode: true
agent_enabled: false
<<: *default_settings
config/puma.rb
require 'puma_worker_killer'
ActiveRecord::Base.connection_pool.disconnect!
PumaWorkerKiller.config do |config|
config.ram = ENV['PUMA_WORKER_KILLER_RAM'] || 1024 # mb
config.frequency = 5 # seconds
config.percent_usage = 0.98
config.rolling_restart_frequency = 12 * 3600 # 12 hours in seconds
end
PumaWorkerKiller.start
end
workers Integer(ENV['WEB_CONCURRENCY'] || 5)
min_threads_count = Integer(ENV['MIN_THREADS'] || 1)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads min_threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
# #sidekiq_pid ||= spawn('bundle exec sidekiq -c 2 -q default -q mailers')
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
end
end
config/initializers/sidekiq.rb
require 'sidekiq'
redis_url = ENV['REDISTOGO_URL']
redis_config = {
url: redis_url,
namespace: 'oct',
}
Sidekiq.configure_server do |config|
config.redis = {
url: ENV["REDISTOGO_URL"], namespace: 'app',
size: ENV["SIDEKIQ_SERVER_CONNECTIONS"].to_i || 6
}
config.error_handlers << Proc.new do |exception, context_hash|
SidekiqErrorService.new(exception, context_hash).notify
end
end
Sidekiq.configure_client do |config|
config.redis = {
url: ENV["REDISTOGO_URL"], namespace: 'app',
size: ENV["REDIS_CLIENT_CONNECTION_SIZE"].to_i || 2
}
end
So I believe it was the New Relic Browser JS that I included in the head of my pages. Once I set that to - if production_environment? (my helper method), then I only saw production environment traffic.
I believe that something in that JS was pinging my New Relic.
Fixed now.

Using { host: 'localhost', port: 3000 } in ActionMailer in Production.rb for deployment to VPS?

This is the first time I'm working with actionmailer in production.
Earlier I deployed an App to a VPS server. I haven't assigned a domain to it yet so it is only an IP address.
I configured the action mailer settings, but I'm curious about this line:
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }can I use the Ip address of the server instead of { host: 'localhost', port: 3000 }or does the server act as a localhost after the app is deployed with this setting?
Here is the setup code in the production.rb
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.perform_deliveries = true
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: ENV["SMTP_ADDRESS"],
user_name: ENV["SMTP_USER"],
password: ENV["SMTP_PASSWORD"],
domain: "gmail.com",
port: 587,
authentication: :login,
enable_starttls_auto: true
}
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
Once you have configured this and you use these settings to send the mail via gmail server. The default url will be used as the domain name of website/application like say for forgot password to users.
http://localhost:3000/forgot_password?email="fd#ds.com"
You should be changing this to the domain name or the ip where the application code is hosted. localhost is used only for development setups.

Rails Mailer does not pick up on the host

Site is in sub-directory /app
In development.rb:
config.action_mailer.default_url_options = {
host: 'localhost:3000/app'
}
Url generated in the mailer item_url(1):
localhost/item/1, it should be: localhost:3000/app/item/1
How do I replace localhost with localhost:3000/app?
This is in Rails 4.1.15.
To expand on tadman's comment... Your host should only have the 'localhost' portion and a separate port option:
config.action_mailer.default_url_options = {
host: 'localhost',
port: 3000
}
As for making the app load under /app:
config.relative_url_root = "/app"
(See see Rails app in a subdirectory for details)
Using script_name did the trick:
config.action_mailer.default_url_options = {
host: 'localhost',
port: 3000,
script_name: '/app'
}

Resources